0

次の形式の MYSQL クエリがあります。

SELECT
    employee.name,
    totalpayments.totalpaid
FROM
    employee
    JOIN (
        SELECT
            paychecks.employee_id,
            SUM(paychecks.amount) totalpaid
        FROM
            paychecks
        GROUP BY
            paychecks.employee_id
         ) totalpayments on totalpayments.employee_id = employee.id

私は最近、これが次の形式ではるかに高速に返されることを発見しました:

SELECT
    employee.name,
    (
        SELECT
            SUM(paychecks.amount)
        FROM
            paychecks
        WHERE
            paychecks.employee_id = employee.id
    ) totalpaid
FROM
    employee

速度に違いがあり、下位のクエリの方が高速であることに驚きました。サブクエリを独立して実行できるため、開発には上の形式を好みます。

「両方の長所」を得る方法はありますか: 迅速な結果が返され、サブクエリを分離して実行できるか?

4

2 に答える 2

0

結合は基本的にデカルト積であり、テーブル A のすべてのレコードがテーブル B のすべてのレコードと結合されることを意味します。出力は次のようになります。

number of records of table A * number of records of table b =rows in the new table
10 * 10 = 100

これらの 100 件のレコードのうち、フィルターに一致するレコードがクエリで返されます。

ネストされたクエリには、サンプルの内部クエリがあり、内部クエリのレコードの合計サイズが何であれ、外部クエリへの入力になります。これが、ネストされたクエリが結合よりも高速である理由です。

于 2015-02-11T17:34:37.343 に答える
0

おそらく、相関サブクエリはインデックスを効果的に利用できるため、サブクエリを複数回実行する必要がありますが、高速です。

インライン ビューを使用した最初のクエリでは、MySQL が派生テーブルを作成し、大規模なセットでは実質的に MyISAM テーブルになります。

MySQL 5.6.x 以降では、オプティマイザは派生テーブルにインデックスを追加することを選択する場合があります。これは、それが操作を許可し、ref操作の推定コストがrefネストされたループ スキャンよりも低い場合です。

EXPLAINアクセスプランを見るために使ってみることをお勧めします。(パフォーマンスに関するレポートに基づいて、MySQL バージョン 5.5 以前を実行していると思われます。)


employeesに一致する行がない に行がある場合、2 つのステートメントは完全には同等ではありませんpaychecks

サブクエリを完全に回避して、同等の結果を得ることができます。

SELECT e.name
     , SUM(p.amount) AS total_paid
  FROM employee e 
  JOIN paychecks p
    ON p.employee_id = e.id
 GROUP BY e.id

(内部結合を使用して最初のクエリと同等の結果を取得し、LEFT外部結合を使用して 2 番目のクエリと同等の結果を取得しIFNULLます。の null 以外の値を持つ一致する行がamount給与で見つかります)。

于 2015-02-11T17:24:19.603 に答える