2

100 以上の列と 100 万行の Order テーブルがあるとします。OrderID と FK 制約 StoreID に PK があります --> Store.StoreID。

1)select * from 'Order' order by OrderID desc limit 10;

上記には数ミリ秒かかります。

2)select * from 'Order' o join 'Store' s on s.StoreID = o.StoreID order by OrderID desc limit 10;

これには何秒もかかることがあります。追加する内部結合が増えるほど、速度がさらに低下します。

3)select OrderID, column1 from 'Order' o join 'Store' s on s.StoreID = o.StoreID order by OrderID desc limit 10;

これにより、選択する列が制限されるため、実行速度が向上するようです。

ここで私が理解していない点がいくつかあります.mysql(または一般的なrmdbクエリの実行)に詳しい人が私を啓発してくれると本当にありがたいです.

クエリ 1 は、PK による単なる逆引きであり、DB は最初に検出した 10 行のみを返す必要があるため、高速です。

クエリ 2 が永遠に続く理由がわかりません。操作は同じではないでしょうか?つまり、最初の 10 行を PK で取得してから、他のテーブルと結合します。FK 制約があるため、関係が満たされることが保証されます。したがって、DB は必要以上の行を結合して結果をトリミングする必要はありませんよね? FK 制約がヌル FK を許可しない限り? その場合、左結合はこれを内部結合よりもはるかに高速にすると思いますか?

最後に、これらの不要な結合で使用される列が少ないため、クエリ 3 の方が単純に速いと思いますか? しかし、結合中にクエリの実行で他の列が必要になるのはなぜでしょうか? 最初に PK を使用して結合し、次に 10 行だけの列を取得するべきではありませんか?

ありがとう!

4

2 に答える 2

2

私の理解では、mysql エンジンはlimit何かjoinが発生した後に適用されます。

http://dev.mysql.com/doc/refman/5.0/en/select.htmlから、The HAVING clause is applied nearly last, just before items are sent to the client, with no optimization. (LIMIT is applied after HAVING.)

編集: このクエリを使用して、PK 速度を利用することができます。

select * from (select * from 'Order' order by OrderID desc limit 10) o join 'Store' s on s.StoreID = o.StoreID;

于 2012-11-28T23:49:19.837 に答える
2

すべての例は既存のテーブルのテーブルスキャンを要求しているため、mysql がデータまたは結果をキャッシュできる程度よりもパフォーマンスが高いまたは低いものはありません。一部のクエリには、結合プロセスをより効率的にするためだけにインデックスを利用できる order by または join 基準がありますが、それでも、インデックスの使用をトリガーする一連の基準を持つことと同じではありません。

制限は基準ではありません。結果セットが決定された後のフィルタリングと考えることができます。結果セットが準備されると、クライアントでは時間を節約できますが、サーバーでは時間を節約できません。

本当に、あなたが求めている答えを得る唯一の方法は、よく知ることです: EXPLAIN EXTENDED your_sql_statement

EXPLAIN の出力には、mysql が参照している行数と、インデックスが使用されているかどうかが示されます。

于 2012-11-28T23:51:50.380 に答える