6

私はMS SQLを使用しています。

このクエリを高速化するためのインデックスを持つ巨大なテーブルがあります。

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

1秒以内に戻ります。テーブルには数十億の行があります。約10000件の結果しかありません。

このクエリも約 1 秒で完了すると思います。

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秒かかります。個々のクエリはすべて 1 秒未満で完了し、約 10,000 件の結果が返されます。

SQL が内部的にこれらのサブクエリのそれぞれからの結果をハッシュテーブルにスローし、ハッシュ交差を行うことを期待します-O(n) である必要があります。結果セットはメモリに収まるほど大きいので、IO の問題ではないかと思います。

ネストされた一連の JOIN だけである代替クエリを作成しましたが、これも約 20 秒かかります。これは理にかなっています。

INTERSECT が遅いのはなぜですか? クエリ処理の初期段階で JOIN になりますか?

4

1 に答える 1

14

代わりにこれを試してください。明らかにテストされていませんが、必要な結果が得られると思います。

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
于 2010-12-06T22:50:43.320 に答える