2

任何人都可以帮助我提高以下 sql 的性能。数据库使用的是informix

SELECT 
   informix.set_reason_codes.description as reason_code, 
   count(*) as number_of_calls
FROM 
informix.contact_history,
informix.set_reason_codes,
informix.customers
WHERE 
  (informix.contact_history.reason_code = informix.set_reason_codes.reason_code)
and ( ( informix.set_reason_codes.code_type = 'CONTACT_HISTORY' ) )
and ( informix.contact_history.customerkey = informix.customers.customerkey ) 
and ( informix.contact_history.call_type = 0 ) 
group 
   by informix.set_reason_codes.description  
order by 
   informix.set_reason_codes.description  
4

2 回答 2

3

您需要通过 EXPLAIN ON 运行此 SQL 来获取查询计划,即:

SET EXPLAIN ON;
SELECT ....

这会将优化器的计划写入文件(实际位置取决于操作系统和连接方法)。

一旦你有了这个,你就可以更好地确定性能问题的原因。但通常,它归结为以下其中一项:

  • 不适当的索引
  • 过时或缺少索引统计信息

sqexplain 文件中有关 AUTO-INDEX 或 SEQUENTIAL SCAN 的消息,您会在其中预期 NESTED LOOP(索引连接),这是一个很好的指示,需要进行一些调整。如果不出意外,运行查询并获取解释输出,然后执行,

UPDATE STATISTICS MEDIUM FOR TABLE informix.contact_history;
UPDATE STATISTICS MEDIUM FOR TABLE informix.set_reason_codes;
UPDATE STATISTICS MEDIUM FOR TABLE informix.customers;

如果您在查询计划中得到了显着不同的性能结果和报告,您就知道您的问题与统计信息有关。

了解您正在运行的 Informix 版本也会很有用。

于 2009-09-25T08:28:39.263 回答
2

了解如何使用表别名使 SQL 可读:

SELECT r.description AS reason_code, COUNT(*) AS number_of_calls
  FROM informix.contact_history  AS h,
       informix.set_reason_codes AS r,
       informix.customers        AS c
 WHERE h.reason_code = r.reason_code
   AND r.code_type   = 'CONTACT_HISTORY' 
   AND h.customerkey = c.customerkey 
   AND h.call_type   = 0 
 GROUP BY r.description  
 ORDER BY r.description

避免多余的括号也有帮助。您可以就布局进行辩论 - 但这些方面的内容通常看起来很合理。

改天,我们可以讨论使用用户“informix”作为表所有者的优点或缺点——我建议不要这样做,但有些人坚持认为这是他们的最佳选择。(我不同意他们的推理,但客户永远是对的。)

关于性能,您在评论中说索引是:

  • 对于contact_history,customerkey、date_and_time 和reason_code 的一个索引。
  • 对于 set_reason_codes,code_type 的一个索引,reason_code
  • 对于客户,customerkey 的一个索引

您的部分问题出在此处。您可能会从索引中受益:

CREATE INDEX fk_contact_history ON contact_history(reason_code);

这将有助于加入' h.reason_code = r.reason_code'; 现有的索引对此毫无用处。

您可能会从索引中受益:

CREATE INDEX ix_set_reason_codes ON set_reason_codes(reason_code);

然后我们进入问题的实质;您加入客户表,但似乎没有任何实际理由这样做 - 假设customerkey实际上是customers表的主键。

因此,您将从该查询中得到相同的结果:

SELECT r.description AS reason_code, COUNT(*) AS number_of_calls
  FROM informix.contact_history  AS h,
       informix.set_reason_codes AS r
 WHERE h.reason_code = r.reason_code
   AND r.code_type   = 'CONTACT_HISTORY' 
   AND h.call_type   = 0 
 GROUP BY r.description  
 ORDER BY r.description
于 2009-09-27T02:38:41.837 回答