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.我们两个人独立地获得了相同的结果,将相同的备份恢复到两台不同的计算机.
其他详情:
>即使在慢速查询中,括号内的位也会在不到一秒的时间内运行
>执行计划中可能存在一些线索,我不明白.这是它的一部分,有可疑的320,000,000行操作:
但是,该表上的实际行数略多于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:
更新统计数据也没有区别.
感谢您到目前为止的所有建议.
解决方法
所以代替:
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