2

SQL Server 2012 LocalDB を使用しています。

クライアントは、200 (!) 列のnvarchar(max)値からそれぞれ (信じられないかもしれませんが) 構成されている 2 つのテーブルを比較するように求めています。インデックスはなく、一意のキーもありません。

私は見つける方法をグーグルで検索しました(http://weblogs.sqlteam.com/jeffs/archive/2004/11/10/2737.aspx)。メソッドは機能します。ただし、union all / group by 式で 200 列を使用すると、少し遅くなります。

クエリは次のようになります

SELECT 
    MIN(TableName) as TableName , header1, header2, header3, header....
INTO RESULTS  
FROM 
    (SELECT 
        'table1' as TableName, table1.header1, table1.header2, table1.header3, table1.header...
     FROM table1 

     UNION ALL 

     SELECT 
         'table2' as TableName , table2.header1, table2.header2, table2.header3, table2.header...
    ) tmp 
GROUP BY 
    header1, header2, header3, header...
HAVING 
    COUNT(*) = 1

最初のクエリの実行計画

私の考えは、ここ ( http://www.bidn.com/blogs/TomLannen/bidn-blog/2265/using-hashbytes-to-compare-columns ) で説明されているように、任意の行のハッシュバイト値を計算し、それを追加の列 (この場合、もう 1 つ追加しても問題ありません :-) )。hashbytes 自体は非常に高速に計算されますが、その後、union all / group by /having 句で hashbyte 値のみを使用してクエリを実行すると、クエリが非常に遅くなります。最初のケースでは約 25 秒かかりましたが、約 15 分実行されます。

2 番目のクエリは次のようになります (compareHash が挿入された hashbyte 列です)。

SELECT 
    MIN(TableName) as TableName, compareHash 
INTO RESULTS  
FROM 
   (SELECT 
       'table1' as TableName , compareHash 
    FROM table1 

    UNION ALL 

    SELECT 
       'table2' as TableName , compareHash 
    FROM table2) tmp 
GROUP BY 
    compareHash 
HAVING 
    COUNT(*) = 1

2 番目のクエリの実行計画 私は正反対のことを期待していたでしょう。誰かがこの行動の理由について考えることができますか?

よろしくセバスチャン

4

1 に答える 1

0

クエリ プランを見ると、2 番目のクエリで返される行が大幅に少ない (矢印の太さから判断) ことがわかります。

これにより、列に正しくデータを入力したかどうか疑問に思いcompareHashます。つまり、200 列すべてが正しくハッシュに含まれている場合です。

どちらかといえば、文字データをハッシュすると比較で大文字と小文字が区別されるため、2 番目のクエリではより多くの行が返されることが予想されます。SQL Server の既定の照合では、varchar 値に対する最初のクエリで大文字と小文字を区別しない比較が実行されます。

これは正確性と関係がありますが、通常、パフォーマンスを比較するときは同じ答えが得られるアプローチを比較します。


正確さはさておき、もう 1 つの観察結果は、最初のクエリでデータが並べ替えられてから、ストリーミング集計が適用されることです。2 番目のクエリでは、ハッシュ テーブルが作成され、2 番目のテーブルを使用してハッシュ テーブルがプローブされます。クエリの最後に追加することで、2 番目のクエリで並べ替えられたストリーミング集計プランを強制し、OPTION (ORDER GROUP)それによって実行時間が変わるかどうかを確認できますが、改善されるとは思えません。

私の推測では、元の varchar データには、SQL サーバーが最初のクエリで利用している自然な順序があります。

列にインデックスを作成する場合compareHashは、マージ結合を使用するため、2 番目のクエリでパフォーマンスが大幅に向上する可能性があります。

于 2012-10-09T21:48:39.393 に答える