数据库于周日被重启了,刚好看看优化后的效果,顺便再找找新的需要优化的SQL 刚好找到了类似的几条语句,如下 select * from tableA where id not in (select id from tableB) 从执行时间20秒~70秒不等。 开始分析 首先是否用上索引,两个id均是主键所以不存在索引问题 其次分析一下索引,发现这两个id虽然是主键,但却不是聚集索引,而且id是通过newid()生成的完全无序的,因此这两个表在索引上可以说毫无用处,因为完全都是无序的。 换个思路,如果这两个id都是排序的,而且记录数也都不算少,再进行关联是不是会很快呢?还好SQLServer提供了Merge Join的hint提示,试试看吧 select * from tableA where id not in (select id from tableB) OPTION (MERGE JOIN); 执行后出现以下错误: 消息 8622,级别 16,状态 1,第 1 行 由于此查询中定义了提示,查询处理器未能生成查询计划。请重新提交查询,并且不要在查询中指定任何提示,也不要使用 SET FORCEPLAN。 查了以下相关文档,也就是说该语句不支持OPTION (MERGE JOIN); 那么换成not exists再试一下,看看效果是否会好一些 select * from tableA where not exists(select 1 from tableB where tableA.id=tableb.id) 通过测试后,发现稍微速度提高了一点点 最后再添加上OPTION (MERGE JOIN),试试看,居然变成了0秒 select * from tableA where not exists(select 1 from tableB where tableA.id=tableb.id) OPTION (MERGE JOIN); 调优大获成功,呵呵。 总结: 不是所有相关表都一定要建索引(或者聚合索引),以后可以多试试SQLServer的查询提示。
本文转自baoqiangwang51CTO博客,原文链接:http://blog.51cto.com/baoqiangwang/360268,如需转载请自行联系原作者