有一个相当复杂的SQL Server查询,我一直试图优化几个月,尽管多个索引添加(添加覆盖,非聚集索引)和查询重构/更改需要很长时间来执行。没有深入细节,执行计划如下。在这里有什么东西可以跳出来,特别是效率低下或者不好?我摆脱了所有重要的查找,似乎大量使用索引查找,这就是为什么我感到困惑,它仍然需要大量的时间。当查询运行时,瓶颈显然是CPU(而不是磁盘I/O)。非常感谢您的任何想法。艰难的SQL优化
艰难的SQL优化
回答
行,所以我做了基于马丁的意见这似乎已经极大地帮助了查询速度的变化。我不是100%肯定的,这是解决方案BC我一直在运行这个很多,有可能这么多的基础数据已经被放入内存,它现在是快速的。但我认为实际上有一个真正的差异。
具体而言,嵌套循环内部的3次扫描是由非常小的表上的子查询引起的,这些表包含一小部分要完全从结果集中排除的记录。从概念上讲,查询是这样的:
SELECT fields
FROM (COMPLEX JOIN)
WHERE id_field NOT IN (SELECT bad_ID_field FROM BAD_IDs)
的想法是,如果一个记录出现在BAD_IDs它不应该被包含在结果中。
我修修补补这个并将其更改为类似:
SELECT fields
FROM (COMPLEX JOIN)
LEFT JOIN BAD_IDs ON id_field = bad_ID_field
WHERE BAD_IDs.bad_ID_field IS NULL
这是逻辑上是相同的东西 - 它排除了在BAD_IDs任何ID结果 - 但它使用一个连接,而不是一个子查询。即使执行计划几乎相同, TOP操作被更改为树中其他位置的FILTER,但聚簇索引扫描仍然存在。
但是,它似乎运行速度更快!这是预期的吗?我一直认为以我所采用的方式使用的子查询是可以的,并且服务器会知道如何创建最快的(并且大致相同的,几乎相同的)执行计划。这是不正确的?
Thx!
通常我会将所有'NOT IN(SELECT ...)重写为'NOT EXISTS'。曾几何时,查询规划人员可以更好地优化。在更高版本的SQL中,这可能没有任何区别。 –
@ Nick.McDermaid - 它取决于列的可空性。我认为他们不是空的,因为我没有看到原计划中处理可能的空值的额外设备。 https://stackoverflow.com/a/11074428/73226 –
新计划是什么样的? –
- 1. IDLE的艰难时刻
- 2. 艰难的Mysql查询
- 3. Django的一个艰难的关系
- 4. Android - 相机,非常艰难的任务
- 5. 猛击一个艰难的FRAME杀手
- 6. 艰难jQuery的模板问题
- 7. 学习Python艰难的历程 - ex18
- 8. 调试一个艰难的LINQ到SQL超时
- 9. 很难优化查询
- 10. 处境艰难时呼叫机器人
- 11. 二维数组让我处境艰难
- 12. 艰难地在El Capitan上安装Jekyll
- 13. 艰难的T-SQL显示组织结构图(层次结构/递归)
- 14. 优化我的SQL
- 15. 的Oracle SQL优化
- 16. SQL Server优化
- 17. SQL优化
- 18. 优化SQL
- 19. SQL优化
- 20. SQL优化
- 21. SQL DECODE优化
- 22. SQL优化(MySQL)
- 23. 艰难的Wordpress有条件的if_page不显示小部件
- 24. 用Java处理数组。困于艰难的作业任务
- 25. CakePHP:不确定如何处理半艰难的关系
- 26. 与终端用户艰难的第二十二条军规
- 27. 真正的艰难:如何将单列插入多列?
- 28. 艰难的CSS问题 - 从其他属性获取值?
- 29. 优化/简化游标sql
- 30. 优化SQL查询
你还可以显示你的查询和表/索引结构吗? – Siyual
另外,将实际的XML计划上传到https://www.brentozar.com/pastetheplan/ –
'这里有什么特别低效或坏的东西跳出来吗?'是的。这3个扫描在嵌套循环内部连接.https://i.stack.imgur.com/RrUxh.png –