3

誰かが私になぜこれを説明してもらえますか:

SELECT 
    A.id,
    A.name,
    B.id AS title_id
FROM title_information AS A
JOIN titles B ON B.title_id = A.id
WHERE
    A.name LIKE '%testing%'

これよりもかなり遅い(6〜7倍):

SELECT 
    A.id,
    A.name,
    B.id AS title_id
FROM (SELECT id, name FROM title_information) AS A
JOIN titles B ON B.title_id = A.id
WHERE
    A.name LIKE '%testing%'

スキーマと MySQL 構成の詳細を知らずにこの質問に答えるのはおそらく難しいと思いますが、最初の例が 2 番目の例よりも大幅に遅くなる可能性がある一般的な理由を探していますか?

EXPLAIN を実行すると、次のようになります。

|| *id* || *select_type* || *table*  || *type*  || *possible_keys*           || *key*   || *key_len* || *ref*             || *rows* || *Extra*     ||
|| 1    || SIMPLE        || B        || index   ||                           || id      || 12        ||                   || 80407  || Using index ||
|| 1    || SIMPLE        || A        || eq_ref  || PRIMARY,id_UNIQUE,Index 4 || PRIMARY || 4         || newsql.B.title_id || 1      || Using where ||

|| *id* || *select_type* || *table*           || *type* || *possible_keys* || *key*   || *key_len* || *ref* || *rows* || *Extra*                         ||
|| 1    || PRIMARY       || B                 || index  ||                 || id      || 12        ||       || 80407  || Using index                     ||
|| 1    || PRIMARY       || <derived2>        || ALL    ||                 ||         ||           ||       || 71038  || Using where; Using join buffer  ||
|| 2    || DERIVED       || title_information || index  ||                 || Index 4 || 206       ||       || 71038  || Using index                     ||

更新: A.id と B.id は両方とも PRIMARY KEYS ですが、A.name はインデックスです。両方のテーブルには、約 50,000 行 (~15MB) があります。MySQL の設定はほとんどデフォルトです。

それが役立つかどうか(または、それが混乱をさらに助長するかどうか-私の場合のように)はわかりませんが、より多くの一致するフィールドを持つ可能性が高いより一般的な LIKE ステートメントを使用すると(例:"LIKE '%x%'")、最初のクエリが作成されますかなり速く走る。一方、「LIKE '%there are no records matching this%'」を使用すると、2 番目のクエリが大幅に高速化されます (最初のクエリは苦労します)。

ここで何が起こっているのか、誰でも光を当てることができますか?

ありがとうございました!

4

1 に答える 1

0

これは憶測です (データフロー図を見たいので、MySQL Explain の出力を読む力が本来よりも弱いのです)。

しかし、ここで私は何が起こっていると思います。最初のクエリは、「B を調べて、A の適切な値を調べましょう」というものです。次に、インデックスを使用して適切な値を検索しid、ページを取得して と比較する必要がありますname。これらのアクセスはシーケンシャルではないため、非効率的です。

2 番目のバージョンは、オンの条件nameが重要であると認識しているようです。Aのインデックスを通過し、name必要に応じて一致する行のみをフェッチします。データがインデックスにあり、一致する名前に必要なページが少ないため、これは高速です。B との一致は非常に単純で、一致する行は 1 つだけです。

性能差にビックリです。通常、派生テーブルはパフォーマンスが悪いですが、これは明らかに例外です。

于 2013-09-03T21:38:58.113 に答える