【问题标题】:Why is INTERSECT as slow as a nested JOIN?为什么 INTERSECT 和嵌套 JOIN 一样慢?
【发布时间】:2011-05-21 06:38:14
【问题描述】:

我正在使用 MS SQL。

我有一个带有索引的巨大表来加快这个查询:

select userid from IncrementalStatistics where
IncrementalStatisticsTypeID = 5 and
IncrementalStatistics.AssociatedPlaceID = 47828 and
IncrementalStatistics.Created > '12/2/2010

它会在不到 1 秒的时间内返回。该表有数十亿行。只有大约 10000 个结果。

我希望这个查询也能在大约一秒钟内完成:

select userid from IncrementalStatistics where
IncrementalStatisticsTypeID = 5 and
IncrementalStatistics.AssociatedPlaceID = 47828 and
IncrementalStatistics.Created > '12/2/2010'

intersect

select userid from IncrementalStatistics where
IncrementalStatisticsTypeID = 5 and
IncrementalStatistics.AssociatedPlaceID = 40652 and
IncrementalStatistics.Created > '12/2/2010'

intersect

select userid from IncrementalStatistics where
IncrementalStatisticsTypeID = 5 and
IncrementalStatistics.AssociatedPlaceID = 14403 and
IncrementalStatistics.Created > '12/2/2010'

但这需要 20 秒。所有单个查询都需要

我希望 SQL 在内部将这些子查询中的每一个的结果放入哈希表并进行哈希交集 - 应该是 O(n)。结果集足够大,可以放入内存,所以我怀疑这是 IO 问题。

我编写了一个替代查询,它只是一系列嵌套的 JOIN,这也需要大约 20 秒,这是有道理的。

为什么 INTERSECT 这么慢?它是否在查询处理的早期阶段减少为 JOIN?

【问题讨论】:

  • “我怀疑这是一个 io 问题”-> 解释计划说查询中最昂贵的部分是什么?
  • MS SQL 是否有 EXPLAIN 或某种方式来查看查询计划?根据其他人的回答,听起来 INTERSECT 实现并不聪明......
  • @Brendan - 是的,查询计划有一个很好的可视化。这个查询似乎不够微妙,不需要求助 - 我正在寻找直观的论点。

标签: sql algorithm join query-optimization intersect


【解决方案1】:

试试这个吧。显然未经测试,但我认为它会得到你想要的结果。

select userid 
    from IncrementalStatistics 
    where IncrementalStatisticsTypeID = 5 
        and IncrementalStatistics.AssociatedPlaceID in (47828,40652,14403)  
        and IncrementalStatistics.Created > '12/2/2010'
    group by userid
    having count(distinct IncrementalStatistics.AssociatedPlaceID) = 3

【讨论】:

  • 老兄!那快了一吨。我想了解为什么?看起来它实际上比上面做了更多的工作。
  • @John Shedletsky:这更快,因为它是对 IncrementalStatistics 表的单次传递,而不是 3 个完全独立的查询。
  • @Joe:我怀疑这就是它这么快的原因。相交 2 组 10000 个内存字符串在任何 PC 上都花费不到 1 秒,因此 John 的查询可能花费超过 3*1+1+1=5s 的唯一原因是因为数据库引擎为其选择了一个糟糕的计划原始查询。
  • @John:如果您正在寻找一个具有“正确答案”的面试问题(而不是仅仅看到候选人通过各种可能性工作),我认为这不是一个好的选择,因为它取决于了解 MS SQL 查询计划器的不可知的内部行为。很抱歉这么否定,很高兴乔的回答对你有用,但这真的只是平局的运气(正如他所说,两个版本在他的系统上非常相似)。
  • group by ... having count()的好用法
猜你喜欢
  • 2015-03-27
  • 2020-04-03
  • 2015-03-03
  • 1970-01-01
  • 2011-02-20
  • 2019-10-09
  • 2017-01-18
  • 1970-01-01
相关资源
最近更新 更多