2009-09-25 26 views
2

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

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 
+0

什么指标都存在这些表? – 2009-09-25 07:42:45

+0

对于contact_history一个指数customerkey,DATE_AND_TIME和REASON_CODE 对于集REASON_CODES一个指数code_type,REASON_CODE 对于客户一个指数customerkey – Shalma 2009-09-25 07:54:33

回答

3

您需要通过运行该SQL使用EXPLAIN ON获得查询计划,即:

SET EXPLAIN ON; 
SELECT .... 

这将优化器的计划写入一个文件(实际位置取决于OS和连接方法)。

一旦你有了这个,你将处于一个更好的位置,以确定你的性能问题的原因。但通常情况下,把它归结为这些东西:

  • 不合适的指标
  • 过时的或关于自动索引或顺序扫描,你的sqexplain文件丢失索引统计信息

消息预计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版本也很有用。

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 
+0

我使用别名绝对同意(我被带到一个家伙在Informix的工作,相信即使查询中只有一个表,也会提高性能)。 但是,如果contact_history.customerkey不能为空,则省略与customerkey的连接只会始终返回相同的行。如果它是可空的,那么原始查询将只返回链接到客户行中的contact_history行;建议的替换将返回contact_history中的所有行。 Shalma认为这是正确的。 – sanmiguel 2010-03-24 18:13:23