3

私の仕事の 1 つは、データベースを維持することです。通常、レポートを取得してそのベースで作業しているときに、パフォーマンスが低下するという問題が発生します。
ERP がデータベースに送信するクエリを見始めると、メイン クエリ内に完全に不必要なサブセレクト クエリが多数表示されます。
私は私たちが使用しているプログラムの作成者である開発者のメンバーではないので、私が彼らのコードや仕事を批判しても彼らはあまり好きではありません. 彼らが私のレビューを深刻な声明と見なしていないとしましょう。そこで、SQL の副選択についていくつか質問します。

副選択は、左外部結合よりも多くの時間を費やしていますか?
使用しないことをお勧めするブログ、記事、または副選択したものはありますか?
クエリで subselectesct を回避すると、そのクエリが高速になることをどのように証明できますか?

データベース サーバーは MSSQL2005 です

4

6 に答える 6

5

"見せてはいけません" - SQL プロファイラーを使用して識別されたクエリのクエリ プランを調べて比較します。特に、テーブル スキャンとブックマーク ルックアップに注意してください (できるだけ頻繁にインデックス シークを確認する必要があります)。クエリ プランの「適合度」は、最新の統計、定義されているインデックス、全体的なクエリ ワークロードに依存します。

SQL Server Management Studio (SSMS) でクエリを実行し、クエリ -> 実際の実行計画を含める (CTRL+M) をオンにします。

幸運なことに、これらは副選択のみであり (場合によっては、オプティマイザーが同等の「結合プラン」を生成します)、相関サブクエリではありません!

多数の論理読み取りを実行しているクエリを特定し、好みの手法を使用して書き直してから、論理読み取りがどれだけ少ないかを比較して示します。

ここにヒントがあります。実行された論理読み取りの合計数を取得するには、問題のクエリを次のようにラップします。

SET STATISTICS IO ON
GO

-- Run your query here

SET STATISTICS IO OFF
GO

クエリを実行し、結果ペインのメッセージ タブに切り替えます。

詳細を知りたい場合は、SQL Server 2008 Query Performance Tuning Distilledほど優れた本はありません。この本では、パフォーマンスの問題を監視、解釈、および修正するための基本的な手法が説明されています。

于 2010-12-28T12:34:33.257 に答える
2

できることの 1 つは、SQL プロファイラーをロードして、サブクエリのコスト (CPU サイクル、読み取り、書き込みの観点から) を表示することです。冷静で厳しい統計に反論するのは難しい。

また、これらのクエリのクエリ プランをチェックして、適切なインデックスが使用されていること、およびテーブル/インデックス スキャンが最小限に抑えられていることを確認します。

一般に、正しく使用され、適切なインデックスが配置されていれば、サブクエリが悪いとは言いません。

于 2010-12-28T12:33:09.677 に答える
1

副選択は、左外部結合よりも多くの時間を費やしていますか?

これは、副選択と左外部結合に依存します。

一般に、この構造は次のとおりです。

SELECT  *
FROM    mytable
WHERE   mycol NOT IN
        (
        SELECT  othercol
        FROM    othertable
        )

これよりも効率的です:

SELECT  m.*
FROM    mytable m
LEFT JOIN
        othertable o
ON      o.othercol = m.mycol
WHERE   o.othercol IS NULL

ここを参照してください:

subselect を使用しないことを推奨するブログ、記事、または何かが存在しますか?

サブセレクトを避けることをやみくもに推奨しているブログには近づきません。

それらは何らかの理由で実装されており、信じられないかもしれませんが、開発者はそれらを最適化するためにいくらかの努力を払ってきました。

クエリで subselectesct を回避すると、そのクエリが高速になることをどのように証明できますか?

より高速に実行される副選択なしでクエリを記述します。

ここにクエリを投稿していただければ、改善できる可能性があります。ただし、副選択のあるバージョンの方が高速であることが判明する場合があります。

于 2010-12-28T16:30:55.460 に答える
1

ほとんどのアプリケーションで postrgesql を使用しているため、MSSQL にはあまり詳しくありません。ただし、クエリの実行計画を示す「EXPLAIN」のようなものが存在するはずです。そこでは、必要なデータを取得するためにクエリが生成するさまざまな手順を確認できるはずです。

インデックスを使用せずに多くのテーブル スキャンまたはループ結合が見られる場合は、間違いなくクエリ実行が遅いことを示しています。このようなツールを使用すると、2 つのクエリを比較できるはずです (1 つは結合あり、もう 1 つは結合なし)。

オプティマイザーがさまざまなケースで使用できるインデックスに大きく依存し、DBMS によっては、オプティマイザーが暗黙的にサブクエリ クエリをジョイン クエリに書き換えることができるため、どちらがより良い方法であるかを述べるのは困難です。それを実行します。

どちらが優れているかを本当に示したい場合は、両方を実行して、時間、CPU 使用率などを測定する必要があります。

更新: おそらくこれは MSSQL 用のものです --> QueryPlan

于 2010-12-28T12:41:15.650 に答える
1

私自身の経験から、両方の方法が有効である可能性があります。たとえば、EXISTS サブセレクトは、早期の中断で多くの処理を回避できます。

しかし、ほとんどの場合、多くの副選択を伴うクエリは、SQL を本当に理解しておらず、従来の手続き型プログラマーのクエリに対する考え方を使用している開発者によって行われます。次に、結合について考えることさえせず、いくつかのひどいクエリを作成します。だから私は結合を好み、常にサブクエリをチェックします。完全に正直に言うと、私は遅いクエリを追跡しており、サブセレクトを含む遅いクエリで最初に試みたのは結合です。多くの時間働きます。

しかし、副選択が結合よりも悪いか遅いかを確立できるルールはありません。それは、悪いSQLプログラマーがしばしば副選択を行うということです:-)

于 2010-12-28T12:43:20.353 に答える
0

一部のクエリを書き直して、サブセレクトと比較ランタイムを排除してみてください。

共有してお楽しみください。

于 2010-12-28T12:59:58.393 に答える