sql-server – 为什么一个查询非常慢,但在类似的表上相同的查询
我有这个查询……运行速度非常慢(差不多一分钟):
select distinct main.PrimeId from PRIME main join ( select distinct p.PrimeId from PRIME p left outer join ATTRGROUP a on p.PrimeId = a.PrimeId or p.PrimeId = a.RelatedPrimeId where a.PrimeId is not null and a.RelatedPrimeId is not null ) mem on main.PrimeId = mem.PrimeId PRIME表有18k行,并且在PrimeId上有PK. ATTRGROUP表有24k行,在PrimeId,col2上有复合PK,然后是RelatedPrimeId,然后是cols 4-7. RelatedPrimeId上还有一个单独的索引. 查询最终返回8.5k行 – PRIME表上的PrimeId的不同值,与ATTRGROUP表上的PrimeId或RelatedPrimeId匹配 我有相同的查询,使用ATTRADDRESS而不是ATTRGROUP. ATTRADDRESS具有与ATTRGROUP相同的密钥和索引结构.它只有11k行,不过可以肯定它是小的,但在这种情况下,查询运行大约一秒钟,并返回11k行. 所以我的问题是: 尽管结构相同,但查询如何在一个表上比另一个表慢得多. 到目前为止,我已经在SQL 2005上尝试了这一点,并且(使用相同的数据库,已升级)SQL 2008 R2.我们两个人独立地获得了相同的结果,将相同的备份恢复到两台不同的计算机. 其他详情: >即使在慢速查询中,括号内的位也会在不到一秒的时间内运行 但是,该表上的实际行数略多于24k,而不是320M! 如果我在括号内重构查询的一部分,那么它使用UNION而不是OR,因此: select distinct main.PrimeId from PRIME main join ( select distinct p.PrimeId from PRIME p left outer join ATTRGROUP a on p.PrimeId = a.PrimeId where a.PrimeId is not null and a.RelatedPrimeId is not null UNION select distinct p.PrimeId from PRIME p left outer join ATTRGROUP a on p.PrimeId = a.RelatedPrimeId where a.PrimeId is not null and a.RelatedPrimeId is not null ) mem on main.PrimeId = mem.PrimeId …然后慢速查询需要一秒钟. 我非常感谢对此的任何见解!如果您需要更多信息,请告诉我,我会更新问题.谢谢! 顺便说一句,我意识到在这个例子中有一个冗余连接.这不容易被删除,因为在生产中,整个事物是动态生成的,括号中的位采用许多不同的形式. 编辑: 我在ATTRGROUP上重建了索引,没有太大的区别. 编辑2: 如果我使用临时表,那么: select distinct p.PrimeId into #temp from PRIME p left outer join ATTRGROUP a on p.PrimeId = a.PrimeId or p.PrimeId = a.RelatedPrimeId where a.PrimeId is not null and a.RelatedPrimeId is not null select distinct main.PrimeId from Prime main join #temp mem on main.PrimeId = mem.PrimeId …然后,即使在原始的OUTER JOIN中使用OR,它也会在不到一秒的时间内运行.我讨厌像这样的临时表,因为它总是感觉像是承认失败,所以它不是我将要使用的重构,但我觉得有趣的是它会产生这样的差异. 编辑3: 更新统计数据也没有区别. 感谢您到目前为止的所有建议. 解决方法根据我的经验,最好在JOIN子句中使用两个左连接而不是OR.所以代替: left outer join ATTRGROUP a on p.PrimeId = a.PrimeId or p.PrimeId = a.RelatedPrimeId 我会建议: left outer join ATTRGROUP a on p.PrimeId = a.PrimeId left outer join ATTRGROUP a2 on p.PrimeId = a2.RelatedPrimeId (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |