1

これこの質問に関連するSQLの質問があります(ただし異なります)。基本的に、ネストされたクエリを回避する方法を知りたいです。

jobsある会社がその歴史の中で実行した膨大な数の仕事()があるとしましょう。これらのジョブは、年、月、場所、およびジョブに使用されるツールに属するコードによって特徴付けられます。さらに、ツールの表(tools)があり、ツールコードをツールの説明とツールに関する詳細データに変換しています。今、彼らはドロップダウンボックスを使用して年、月、場所、ツールを選択できるWebサイトを望んでいます。その後、一致するジョブが表示されます。最後のドロップダウンに、前に選択した年、月、場所に一致する関連ツールのみを入力したいので、次のネストされたクエリを記述します。

SELECT c.tool_code, t.tool_description
FROM (
 SELECT DISTINCT j.tool_code
 FROM jobs AS j
 WHERE j.year = ....
        AND j.month = ....
 AND j.location = ....
) AS c
LEFT JOIN tools as t
ON c.tool_code = t.tool_code
ORDER BY c.tool_code ASC

完全なデータベースでJOINを実行してそこから選択するよりもはるかに高速だったため、このネストされたクエリに頼りました。クエリ時間が大幅に短縮されました。しかし、最近、MySQLのネストされたクエリは絶対に避けるべきだと読んだので、このアプローチが間違っているのではないかと思います。クエリを別の方法で書き直す必要がありますか?そしてどうやって?

4

2 に答える 2

2

いいえ、すべきではありません。クエリは問題ありません。

にインデックスを作成するだけjobs (year, month, location, tool_code)tools (tool_code)INDEX FOR GROUP-BYを使用できます。

提供された記事IN (SELECT ...)では、ネストされたクエリ()ではなく、サブクエリの述語()について説明していますSELECT FROM (SELECT ...)

サブクエリがあっても、記事は間違っています。MySQLすべてのサブクエリを最適化することはできませんが、IN (SELECT …)述語は問題なく処理されます。

著者がここに置くことを選んだ理由はわかりませんDISTINCT

SELECT  id, name, price
FROM    widgets
WHERE   id IN
        (
        SELECT  DISTINCT widgetId
        FROM    widgetOrders
        )

そして、なぜこれがパフォーマンスの向上に役立つと彼らが考えるのか、しかしそれwidgetIDが索引付けされているとすると、MySQLこのクエリを変換するだけです:

SELECT  id, name, price
FROM    widgets
WHERE   id IN
        (
        SELECT  widgetId
        FROM    widgetOrders
        )

index_subquery

EXISTS基本的に、これは句と同じです。内部サブクエリはwidgets、追加の述語を追加して、行ごとに1回実行されます。

SELECT  NULL
FROM    widgetOrders
WHERE   widgetId = widgets.id

の最初の試合で停止しwidgetOrdersます。

このクエリ:

SELECT  DISTINCT w.id,w.name,w.price
FROM    widgets w
INNER JOIN
        widgetOrders o
ON      w.id = o.widgetId

temporary重複を取り除くために使用する必要があり、はるかに遅くなります。

于 2010-01-25T14:34:47.823 に答える
2

を使用してサブクエリを回避することもできますがGROUP BY、サブクエリのパフォーマンスが向上する場合は、それを維持してください。

なぜ参加するのLEFT JOINに代わりに使用するのですか?JOINtools

于 2010-01-25T14:36:55.970 に答える