提高informix中sql的性能
Posted
技术标签:
【中文标题】提高informix中sql的性能【英文标题】:Increasing the performance for the sql in informix 【发布时间】:2009-09-25 07:30:59 【问题描述】:任何人都可以帮助我提高以下 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
【问题讨论】:
这些表上有哪些索引? 对于contact_history 为customerkey、date_and_time 和reason_code 的一个索引 为设置reason_codes 为code_type 的一个索引,reason_code 为customers 为customerkey 的一个索引 【参考方案1】:你需要通过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 版本也很有用。
【讨论】:
【参考方案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);
然后我们进入问题的实质;您加入 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
【讨论】:
我绝对同意使用别名(在 Informix 工作的一个人引导我相信,即使查询中只有一个表,这也会提高性能)。但是,如果 contact_history.customerkey 不能为空,则忽略与 customerkey 的连接只会导致返回相同的行。如果它可以为空,那么原始查询将仅返回与客户中的一行相关联的contact_history 行;建议的替换将返回contact_history 中的所有行。对于这种情况,这取决于夏尔玛。以上是关于提高informix中sql的性能的主要内容,如果未能解决你的问题,请参考以下文章
将存储过程从 MS SQL Server 转换为 Informix