この接続アイテムのサンプルコード
バグを示します
SELECT COUNT(*)
FROM dbo.my_splitter_1('2') L1
INNER JOIN dbo.my_splitter_1('') L2
ON L1.csv_item = L2.csv_item
正しい結果を返します。ただし、次の例では誤った結果が返されます(2014年、新しいCardinality Estimatorを使用)
SELECT
(SELECT COUNT(*)
FROM dbo.my_splitter_1('2') L1
INNER JOIN dbo.my_splitter_1('') L2
ON L1.csv_item = L2.csv_item)
L2の結果が共通のサブ式スプールに誤ってロードされ、L1の結果の結果が再生されるためです。
2つのクエリの動作の違いがなぜなのか興味がありました。トレースフラグ8675は、動作search(0) - transaction processing
するものが入り、失敗するものが入っていることを示していますsearch(1) - quick plan
。
したがって、追加の変換ルールの可用性は動作の違いの背後にあると考えられます(BuildGbApplyまたはGenGbApplySimpleを無効にすると、たとえば修正されるようです)。
しかし、これらの非常によく似たクエリの2つの計画で、異なる最適化フェーズが発生するのはなぜですか?私が読んだことからsearch (0)
、少なくとも3つのテーブルが必要であり、最初の例ではその条件は確かに満たされていません。