すべてのテーブルが比較的小さく (約 2,000 行) あるにもかかわらず、このクエリは 12 秒以上実行されます。
SELECT attr_73206_ AS attr_73270_
FROM object_73130_ f1
LEFT OUTER JOIN (
SELECT id_field, attr_73206_ FROM (
SELECT m.id_field, t0.attr_73102_ AS attr_73206_ FROM object_73200_ o
INNER JOIN master_slave m ON (m.id_object = 73130 OR m.id_object = 73290) AND (m.id_master = 73200 OR m.id_master = 73354) AND m.id_slave_field = o.id
INNER JOIN object_73101_ t0 ON t0.id = o.attr_73206_
ORDER BY o.id_order
) AS o GROUP BY o.id_field
) AS o ON f1.id = o.id_field
どちらのテーブルにもid
、主キーとしてフィールドがあります。また、id_field
、id_order
、attr_73206_
および のすべてのフィールドにmaster_slave
インデックスが付けられます。このクエリのロジックに関しては、全体としてマスター/ディテールのようなものです。表object_73130_
はマスター表、表object_73200_
はディテール表です。それらはmaster_slave
テーブルによってリンクされています。ID によってobject_73101_
フィールドの実際の値を取得するために使用されるアドホック テーブルです。attr_73206_
マスター テーブルの各行に対して、クエリはディテール テーブルの最初の行からフィールドを返します。まず、クエリの外観が変わりましたが、ここでスタックオーバーフローで、このより最適化された構造を使用するようにアドバイスされました (以前に使用されていたサブクエリの代わりに、ところで、クエリがはるかに高速に実行されるようになりました)。最初のサブクエリがJOIN
block は非常に高速に実行されますが、メインのマスター テーブルの行数に匹敵する行数が返されます。いずれにせよ、私はそれを最適化する方法がわかりません。単純な高速実行の結合がなぜこれほど多くの問題を引き起こすのか疑問に思っています。ああ、主な観察結果は、クエリからアドホックを削除しobject_73101_
て ID のみを返し、実際の値を返さない場合、クエリはフラッシュと同じくらい速く実行されるということです。そのため、すべての注意はクエリのこの部分に集中する必要があります
INNER JOIN object_73101_ t0 ON t0.id = o.attr_73206_
クエリ全体がひどく遅くなるのはなぜですか?
編集
このようにして、超高速で実行されます
SELECT t0.attr_73102_ AS attr_73270_
FROM object_73130_ f1
LEFT OUTER JOIN (
SELECT id_field, attr_73206_ FROM (
SELECT m.id_field, attr_73206_ FROM object_73200_ o
INNER JOIN master_slave m ON (m.id_object = 73130 OR m.id_object = 73290) AND (m.id_master = 73200 OR m.id_master = 73354) AND m.id_slave_field = o.id
ORDER BY o.id_order
) AS o GROUP BY o.id_field
) AS o ON f1.id = o.id_field
LEFT JOIN object_73101_ t0 ON t0.id = o.attr_73206_
したがって、アドホック結合をサブクエリの外側に配置しただけであることがわかります。しかし、問題は、サブクエリが自動的に作成され、それを作成するアルゴの部分にアクセスでき、このアルゴを変更でき、クエリ全体を構築するアルゴの部分にアクセスできないことです。私にできることは、サブクエリを何とか修正することだけです。INNER JOIN
とにかく、サブクエリ内でクエリ全体が何百倍も遅くなる理由をまだ理解できません。
編集
テーブルごとに異なるエイリアスを持つ新しいバージョンのクエリ。これはパフォーマンスには影響しません。
SELECT attr_73206_ AS attr_73270_
FROM object_73130_ f1
LEFT OUTER JOIN (
SELECT id_field, attr_73206_ FROM (
SELECT m.id_field, t0.attr_73102_ AS attr_73206_ FROM object_73200_ a
INNER JOIN master_slave m ON (m.id_object = 73130 OR m.id_object = 73290) AND (m.id_master = 73200 OR m.id_master = 73354) AND m.id_slave_field = a.id
INNER JOIN object_73101_ t0 ON t0.id = a.attr_73206_
ORDER BY a.id_order
) AS b GROUP BY b.id_field
) AS c ON f1.id = c.id_field
編集
これはEXPLAIN
コマンドの結果です:
| id | select_type | TABLE | TYPE | possible_keys | KEY | key_len | ROWS | Extra |
| 1 | PRIMARY | f1 | INDEX | NULL | PRIMARY | 4 | 1570 | USING INDEX
| 1 | PRIMARY | derived2| ALL | NULL | NULL | NULL | 1564 |
| 2 | DERIVED | derived3| ALL | NULL | NULL | NULL | 1575 | USING TEMPORARY; USING filesort
| 3 | DERIVED | m | RANGE | id_object,id_master,..| id_object | 4 | 1356 | USING WHERE; USING TEMPORARY; USING filesort
| 3 | DERIVED | a | eq_ref | PRIMARY,attr_73206_ | PRIMARY | 4 | 1 |
| 3 | DERIVED | t0 | eq_ref | PRIMARY | PRIMARY | 4 | 1 |
それの何が問題なのですか?
編集
EXPLAIN
「超高速」クエリのコマンドの結果は次のとおりです
| id | select_type | TABLE | TYPE | possible_keys | KEY | key_len | ROWS | Extra
| 1 | PRIMARY | f1 | INDEX | NULL | PRIMARY | 4 | 1570 | USING INDEX
| 1 | PRIMARY | derived2| ALL | NULL | NULL | NULL | 1570 |
| 1 | PRIMARY | t0 | eq_ref| PRIMARY | PRIMARY | 4 | 1 |
| 2 | DERIVED | derived3| ALL | NULL | NULL | NULL | 1581 | USING TEMPORARY; USING filesort
| 3 | DERIVED | m | RANGE | id_object,id_master,| id_bject | 4 | 1356 | USING WHERE; USING TEMPORARY; USING filesort
| 3 | DERIVED | a | eq_ref | PRIMARY | PRIMARY | 4 | 1 |
閉まっている
上で示した独自の「超高速」クエリを使用します。もう最適化は無理だと思います。