我的任务是在工作中优化一些SQL查询.我发现的一切都指向使用解释计划来识别问题区域.我无法确切地找出解释计划告诉我的问题.您将获得成本,基数和字节.
这表明了什么,我应该如何使用它作为指导.低数字更好吗?高更好?任何投入将不胜感激.
或者,如果您有更好的方法来优化查询,我会感兴趣.
实际上取决于你在做什么,你获得的不仅仅是这些.查看此解释计划页面.我在这里假设您正在使用Oracle并知道如何运行脚本来显示计划输出.开始时可能更重要的是查看左侧是否使用特定索引以及如何使用该索引.如果你正在进行连接,你应该看到诸如"(Full)","(由Index Rowid)"之类的东西.成本将是下一个要考虑的更低成本更好的事情,您会注意到如果您正在进行不使用索引的连接,您可能会获得非常大的成本.您可能还想阅读有关解释计划列的详细信息.
我还假设您使用的是Oracle.我还建议您查看解释计划网页,对于初学者.优化有很多,但可以学习.
一些提示如下:
首先,当有人要求你进行优化时,他们几乎总是在寻找可接受的性能而不是最终性能.如果您可以将查询的运行时间从3分钟缩短到3秒,请不要将其减少到2秒,直到有人要求您为止.
其次,快速检查以确保您正在优化的查询在逻辑上是正确的.这听起来很荒谬,但我无法告诉你我被问及有关慢速运行查询的建议的次数,只是发现它偶尔会给出错误的答案!事实证明,调试查询通常也会加快速度.
特别是,在解释计划中查找短语"Cartesian Join".如果你在那里看到它,你发现无意识的笛卡尔加入的可能性非常大.无意的笛卡尔连接的通常模式是FROM子句列出用逗号分隔的表,连接条件在WHERE子句中.除了缺少其中一个连接条件之外,Oracle除了执行笛卡尔连接外别无选择.对于大型表,这是一场性能灾难.
可以在解释计划中看到笛卡尔加入,其中查询在逻辑上是正确的,但我将其与旧版本的Oracle相关联.
还要查找未使用的复合索引.如果查询中未使用复合索引的第一列,则Oracle可能无效地使用索引,或者根本不使用索引.让我举个例子:
查询是:
select * from customers where State = @State and ZipCode = @ZipCode
(DBMS不是Oracle,因此语法不同,我忘记了原始语法).
快速查看索引会显示客户的索引,其中包含按此顺序排列的列(Country,State,ZipCode).我将查询更改为已读
select * from customers where Country = @Country and State = @State and ZipCode = @ZipCode
现在它运行大约6秒而不是大约6分钟,因为优化器能够使用索引来获得良好的优势.我问应用程序员为什么他们从标准中省略了国家,这就是他们的答案:他们知道所有地址的国家都等于"USA",因此他们认为他们可以通过保留该标准来加快查询速度!
不幸的是,优化数据库检索与缩短计算时间的微秒并不完全相同.它涉及了解数据库设计,尤其是索引,并至少概述优化器如何完成其工作.
当您学习与其协作而不是试图超越它时,通常可以从优化器获得更好的结果.
祝你好运加快优化速度!
你得到了棒棒糖的模糊结束.
在没有大量额外信息和经验的情况下,绝对没有办法查看解释计划并确定哪些(如果有的话)导致性能低于最佳状态.如果查询调整可以简化为10步过程,则可以通过自动化过程完成.我准备列出你需要了解的所有事情才能有效,但这将是一个很长的清单.
我能想到的唯一简短的答案是...寻找计划中的步骤,这些步骤会比您猜测的更多字节.然后考虑如何通过索引或分区来减少该数量.
说真的,拿Jonathan的Lewis书来预算Cost Based Oracle Fundementals
获取Tom Kyte关于Oracle数据库架构的书,并在树林里租了几个小时.