sql >> データベース >  >> RDS >> Sqlserver

SQLServerでの内部結合と左結合のパフォーマンス

    LEFT JOIN INNER JOINよりも絶対に速くはありません 。実際、それは遅いです。定義上、外部結合(LEFT JOIN またはRIGHT JOININNER JOINのすべての作業を行う必要があります 加えて、結果をnull拡張するという余分な作業。また、結果セットのサイズが大きいという理由だけで、より多くの行が返され、合計実行時間がさらに長くなることが予想されます。

    (そして、LEFT JOIN だった 特定でより高速 想像しにくい要因の合流による状況では、機能的にはINNER JOINと同等ではありません。 、したがって、一方のすべてのインスタンスをもう一方のインスタンスに単純に置き換えることはできません!)

    ほとんどの場合、パフォーマンスの問題は、候補キーや外部キーのインデックスが適切に作成されていないなど、他の場所にあります。 9つのテーブルを結合するのは非常に多いため、速度低下は文字通りほとんどどこにでも発生する可能性があります。スキーマを投稿すると、詳細を提供できる場合があります。

    編集:

    これをさらに振り返ると、LEFT JOINが存在する1つの状況を考えることができます。 INNER JOINよりも高速な場合があります 、そのとき:

    • 一部のテーブルは非常に 小さい(たとえば、10行未満)
    • テーブルには、クエリをカバーするのに十分なインデックスがありません。

    この例を考えてみましょう:

    CREATE TABLE #Test1
    (
        ID int NOT NULL PRIMARY KEY,
        Name varchar(50) NOT NULL
    )
    INSERT #Test1 (ID, Name) VALUES (1, 'One')
    INSERT #Test1 (ID, Name) VALUES (2, 'Two')
    INSERT #Test1 (ID, Name) VALUES (3, 'Three')
    INSERT #Test1 (ID, Name) VALUES (4, 'Four')
    INSERT #Test1 (ID, Name) VALUES (5, 'Five')
    
    CREATE TABLE #Test2
    (
        ID int NOT NULL PRIMARY KEY,
        Name varchar(50) NOT NULL
    )
    INSERT #Test2 (ID, Name) VALUES (1, 'One')
    INSERT #Test2 (ID, Name) VALUES (2, 'Two')
    INSERT #Test2 (ID, Name) VALUES (3, 'Three')
    INSERT #Test2 (ID, Name) VALUES (4, 'Four')
    INSERT #Test2 (ID, Name) VALUES (5, 'Five')
    
    SELECT *
    FROM #Test1 t1
    INNER JOIN #Test2 t2
    ON t2.Name = t1.Name
    
    SELECT *
    FROM #Test1 t1
    LEFT JOIN #Test2 t2
    ON t2.Name = t1.Name
    
    DROP TABLE #Test1
    DROP TABLE #Test2
    

    これを実行して実行プランを表示すると、INNER JOINが表示されます。 クエリは確かにLEFT JOINよりもコストがかかります 、上記の2つの基準を満たしているためです。これは、SQLServerがINNER JOINのハッシュ一致を実行したいためです。 、ただし、LEFT JOINのネストされたループを実行します;前者は通常 はるかに高速ですが、行数が非常に少ないため 使用するインデックスはありません。ハッシュ操作はクエリの中で最もコストのかかる部分であることがわかります。

    お気に入りのプログラミング言語でプログラムを作成して、5つの要素を持つリストと、5つの要素を持つハッシュテーブルに対して多数のルックアップを実行することで、同じ効果を確認できます。サイズが大きいため、ハッシュテーブルのバージョンは実際には遅くなります。ただし、50要素または5000要素に増やすと、ハッシュテーブルのO(N)対O(1)であるため、リストバージョンのクロールが遅くなります。

    ただし、このクエリをIDに変更します Nameの代わりに列 非常に異なるストーリーが表示されます。その場合、両方のクエリに対してネストされたループを実行しますが、INNER JOIN versionは、クラスター化されたインデックススキャンの1つをシークに置き換えることができます。つまり、これは文字通り桁違いになります。 行数が多いほど高速になります。

    したがって、結論は、多かれ少なかれ、上記のいくつかの段落で述べたことです。これはほぼ確実にインデックス作成またはインデックスカバレッジの問題であり、1つ以上の非常に小さなテーブルと組み合わされている可能性があります。 SQLServerが可能性があるのは、これらの状況だけです。 INNER JOINに対してより悪い実行プランを選択することがあります LEFT JOINより 。



    1. phpmyadminの結果で推定行数が大きく異なるのはなぜですか?

    2. SQLServerブラウザを起動できません

    3. SQL SELECT MAX

    4. 列ヘッダーを出力テキストファイルに削除します