Database 提高informix中sql的性能

Database 提高informix中sql的性能,database,informix,Database,Informix,有谁能帮助我提高下面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

有谁能帮助我提高下面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  

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

SET EXPLAIN ON;
SELECT ....
这将把Optimizer的计划写入一个文件,实际位置取决于操作系统和连接方法

一旦你有了这些,你就可以更好地找出性能问题的原因。但通常,它归结为以下几点之一:

不适当的索引 过期或缺少索引统计信息 sqexplain文件中有关自动索引或顺序扫描的消息(您可能期望嵌套循环索引联接)是一个非常好的指示器,需要进行一些调整。如果没有其他内容,则运行查询并获取解释输出,然后执行

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版本也很有用。

了解如何使用表别名使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”作为表所有者的优点或缺点——我建议不要这样做,但也有人坚持认为这是他们的最佳选择。我不同意他们的推理,但顾客总是对的

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


对于联系人历史记录,请为customerkey、日期、时间和原因代码创建一个索引。 对于集合\原因\代码,代码类型的索引为“原因\代码” 对于客户,customerkey有一个索引 你的部分问题就在这里。您可能会从索引中受益:

CREATE INDEX fk_contact_history ON contact_history(reason_code);
CREATE INDEX ix_set_reason_codes ON set_reason_codes(reason_code);
这将有助于“h.reason_code=r.reason_code”上的连接;现有的索引对此毫无用处

您可能会从索引中受益:

CREATE INDEX fk_contact_history ON contact_history(reason_code);
CREATE INDEX ix_set_reason_codes ON set_reason_codes(reason_code);
然后我们进入问题的实质;您加入了customer表,但似乎没有任何实际的理由这样做——假设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

这些表上有哪些索引?对于联系人\u历史记录,一个用于customerkey的索引,一个用于设置原因\u代码的日期\u时间和原因\u代码,一个用于代码\u类型的索引,原因\u客户代码customerkey的一个索引我绝对同意使用别名,一个在Informix工作的人让我相信,即使查询中只有一个表,这也会提高性能。但是,忽略与customerkey的联接只会始终导致在contact_history时返回相同的行。customerkey不能为null。如果可以为null,那么原始查询将只返回链接到customers中某一行的contact_历史记录行;建议的替换将返回contact_历史记录中的所有行。这取决于Shalma对这种情况的正确性。