2

次のクエリの背後にあるメカニズムの説明は何ですか?

テーブルで動的フィルタリングを行う強力な方法のように見えます。

CREATE TABLE tbl (ID INT, amt INT)
INSERT tbl VALUES
(1,1),  
(1,1),  
(1,2),
(1,3),
(2,3),  
(2,400),
(3,400),
(3,400)

SELECT *
FROM tbl T1
WHERE EXISTS
  (
    SELECT *
    FROM tbl T2
    WHERE 
       T1.ID = T2.ID AND
       T1.amt < T2.amt
  )

SQL Fiddle でのライブ テスト

4

3 に答える 3

2

通常、明示的な結合を使用して、相関サブクエリを同等の式に変換できます。これが1つの方法です:

SELECT distinct t1.*
FROM tbl T1 left outer join
     tbl t2
     on t1.id = t2.id and
        t1.amt < t2.amt
where t2.id is null

マーティン・スミスは別の方法を示しています。

それらが「動的フィルタリングを行う強力な方法」であるかどうかという問題は真実ですが、(通常は)重要ではありません。他のSQL構造を使用して同じフィルタリングを行うことができます。

相関サブクエリを使用する理由 いくつかの良い点といくつかの悪い点があり、その両方である重要な理由が1つあります。良い面としては、上記のクエリで発生するような行の「乗算」について心配する必要はありません。また、他のフィルタリング条件がある場合、相関サブクエリの方が効率的であることがよくあります。また、削除や更新を使用することもありますが、それがクエリを表現する唯一の方法のようです。

アキレス腱は、多くのSQLオプティマイザーが、ネストされたループ結合として相関サブクエリを実装することです(必須ではありませんが)。そのため、時には非常に非効率になる可能性があります。ただし、あなたが持っている特定の「存在する」構成は、しばしば非常に効率的です。

さらに、テーブル間の結合の性質は、ネストされたサブクエリで失われる可能性があり、where句の条件が複雑になります。より複雑なケースでは、何が起こっているのかを理解するのが難しくなる可能性があります。

私の推薦。大きなテーブルでそれらを使用する場合は、データベースのSQL実行プランについて学習してください。相関サブクエリは、SQLパフォーマンスの最高または最低を引き出すことができます。

可能な編集。これは、OPのスクリプトと同等です。

SELECT distinct t1.*
FROM tbl T1 inner join
     tbl t2
     on t1.id = t2.id and
        t1.amt < t2.amt
于 2012-07-21T12:41:34.390 に答える
1

これを英語に訳してみましょう:

「同じで大きいの行があるtbl場所から行を選択します。」tblIDamt

これが行うことは、 for eachの最大値を持つ行を除くすべてを選択することです。amtID

最後の行SELECT * FROM tblは別のクエリであり、おそらく当面の質問とは関係がないことに注意してください。

于 2012-07-21T11:34:17.157 に答える
0

他の人がすでに指摘しているように、相関サブクエリで EXISTS を使用することは、基本的にデータベース エンジンに「サブクエリで指定された基準を満たす対応するレコードがあるすべてのレコードを返す」ように指示することです。しかし、もっとあります。

EXISTS キーワードはブール値を表します。「WHERE ステートメントの条件に一致するレコードが少なくとも 1 つ存在する場所」という意味にも解釈できます。つまり、単一のレコードが見つかった場合、「完了したので、これ以上検索する必要はありません」ということです。

相関サブクエリで EXISTS を使用することで得られる効率の向上は、EXISTS が TRUE を返すとすぐにサブクエリがレコードのスキャンを停止し、結果を返すという事実から得られます。同様に、NOT EXISTS を使用するサブクエリは、いずれかのレコードがサブクエリの WHERE ステートメントの条件に一致するとすぐに戻ります。

EXISTS を使用したサブクエリは、ネストされたループ検索の使用を避けるためにサポートされているという考えだと思います。ただし、@Gordon Linoff が上記で述べているように、クエリ オプティマイザは、必要に応じて実行される場合と実行されない場合があります。通常、MS SQL Server は EXISTS を最大限に活用していると思います。

私の理解では、すべてのクエリが EXISTS の恩恵を受けるわけではありませんが、多くの場合、特に例のような単純な構造の場合は恩恵を受けます。

私はこれのいくつかを解体したかもしれませんが、概念的には正しい軌道に乗っていると信じています。

注意点は、パフォーマンスが重要なクエリがある場合は、Linoff 氏が示しているように、EXISTS を使用するバージョンと単純な JOINS を使用するバージョンの実行を評価するのが最善だということです。データベース エンジン、テーブル構造、時刻、および月と星の配置によっては、カット アンド ドライではない方が高速になります。

最後の注意 - lc に同意します。サブクエリで SELECT * を使用すると、パフォーマンスの向上の一部またはすべてが無効になる可能性があります。PK フィールドのみを選択します。

于 2012-07-21T13:44:10.390 に答える