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

実行計画でソート演算子を削除して SQL クエリを最適化する

    まず、並べ替えが実際にパフォーマンスのボトルネックであることを確認する必要があります。並べ替えにかかる時間は、並べ替える要素の数によって異なり、特定の親ストアのストアの数は少ない可能性があります。 (これは、where 句を適用した後にソート演算子が適用されることを前提としています)。

    それは過度の一般化です。多くの場合、並べ替え演算子は簡単にインデックスに移動でき、結果セットの最初の数行のみがフェッチされる場合、データベースは一致するすべての行をフェッチする (およびそれらを並べ替える) 必要がないため、クエリのコストを大幅に削減できます。 all) 最初のものを見つけますが、結果セットの順序でレコードを読み取ることができ、十分な数のレコードが見つかったら停止します。

    あなたの場合、結果セット全体を取得しているように見えるので、並べ替えによって事態がさら​​に悪化することはほとんどありません (結果セットが巨大でない限り)。また、あなたの場合、where 句に or が含まれているため、有用なソート済みインデックスを作成するのは簡単ではないかもしれません。

    それでもソート演算子を削除したい場合は、以下を試してください:

    SELECT [Phone]
    FROM [dbo].[Store]
    WHERE [ParentStoreId] = 10
    AND [Type] in (0, 1)
    ORDER BY [Phone]    
      

    または、次のインデックスを試すこともできます:

    CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Phone], [Type])
      

    ParentStoreId でインデックス範囲スキャンを実行するクエリ オプティマイザーを取得する のみ、次にインデックス内の一致するすべての行をスキャンし、Type の場合にそれらを出力します 一致します。ただし、これによりディスク I/O が増える可能性が高いため、クエリの速度が上がるどころか遅くなります。

    編集 :最後の手段として、

    SELECT [Phone]
    FROM [dbo].[Store]
    WHERE [ParentStoreId] = 10
    AND [Type] = 0
    ORDER BY [Phone]
    
    UNION ALL
    
    SELECT [Phone]
    FROM [dbo].[Store]
    WHERE [ParentStoreId] = 10
    AND [Type] = 1
    ORDER BY [Phone]
      

    CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])
      

    アプリケーション サーバー上で 2 つのリストを並べ替えます。ここで、事前に並べ替えられたリストを (マージ並べ替えのように) マージできるため、完全な並べ替えを回避できます。しかし、それは実際にはマイクロ最適化であり、並べ替え自体を桁違いに高速化しますが、ネットワークとディスク I/O がボトルネックであると予想されるため、クエリの合計実行時間に大きな影響を与える可能性は低いです。特に、インデックスがクラスター化されていないため、ディスクが多くのランダム アクセスを行うという事実を考慮してください。




    1. 動的SQLの結果をsql-serverの変数に取得する

    2. mysqlの単一クエリで2つのテーブルを更新します

    3. sequelize(nodejs)を使用してmysqlデータベースを作成する方法

    4. ローリング日付範囲内の個別の値の数を照会します