MySQL Advanced(5)ソートインデックスの最適化
5ソートインデックスの最適化
5.1永遠に小さなテーブルが大きなテーブルを動かす
最適化の原則:小さなテーブルは大きなテーブルを駆動します。つまり、小さなデータセットは大きなデータセットを駆動します
ケース:
SELECT * FROM A WHERE id in (select id from B)
--等价于
for select id from B
for select * from A where A.id = B.id
--for 表示循环
データセットがテーブルBテーブルAデータセットよりも小さい場合、
select * from A where exists( select 1 from B where A.id = B.id)
--等价于
for select * from A
for select * from B where A.id = B.id
--exists:将主查询的数据,放入到子查询中做条件验证,根据验证结果(TRUE或FALSE),来决定主查询的数据是否保留
表Aのデータセットが表Bのデータセットよりも小さい場合、
結論:サブクエリデータセットがメインクエリよりも小さい場合は、で使用します。メインクエリデータセットがサブクエリよりも小さい場合は、を使用します。
5.2キーワードによる順序の最適化
重要な点は、ファイルの並べ替えを回避することです。
最適化の原則:
- 句の順にインデックスインデックスを使用しようと、ソートfilesortレコードを使用することは避けてくださいをソートします。
- インデックス列の並べ替え操作を完了するために、可能な限り、インデックスを作成するときに左端のプレフィックスに従います。
- 注文時にselect *を使用しないようにしてください。多くのバッファーサイズが必要になります。
- ファイルソートソートを使用する必要がある場合は、MySQLパラメータを変更して、双方向ソートまたは一方向ソートを選択できます。
- 双方向ソート:ディスクを2回スキャンし、行ポインターを読み取ってそれらをソートし、列順に並べ替えてから、ソートされたリストに従ってデータを取得します。
- 一方向の並べ替え:ディスクを1回スキャンし、クエリが必要なすべての列を読み取ってから、バッファで並べ替えます。全体的な効率は双方向ソートよりも優れています
- 一方向の並べ替えから生じる問題:一方向の並べ替えは、双方向の並べ替えよりも(メモリ内の)sort_bufferを多く使用します。フェッチされた合計データサイズがサーバーによって構成されたバッファーサイズよりも大きい場合、データの一部が複数回フェッチされ、再度並べ替えられます。 IOの回数が増えました。(MYSQLサーバーのパラメーターを変更し、sort_buffer_sizeとmax_size_for_sort_dataのサイズを増やすことで解決する必要があります)
テストテーブルの構造:
CREATE TABLE tblA(
age int4,
birth TIMESTAMP not null
);
insert into tblA(age,birth) VALUES(22,NOW());
insert into tblA(age,birth) VALUES(23,NOW());
insert into tblA(age,birth) VALUES(24,NOW());
create index idx_tblA_AgeBirth on tblA(age,birth);
select * from tblA
テストケース:
結論:
- MySQLは、ファイルの並べ替えとインデックスの2つの並べ替え方法をサポートしています。インデックスとは、MySQLがインデックス自体をスキャンして並べ替えを完了することを意味し、より効率的です。
- Order byインデックスの並べ替えを使用するには、次の2つの状況を満たす必要があります。Orderbyステートメントは、インデックスの左端の前面の原則を使用します。ASCとDESCが同時に使用される状況はありません。
5.3キーワードによるグループの最適化
- group byの本質は、インデックスによって作成された最も左側のプレフィックスに従って、最初に並べ替えてからグループ化することです。
- 順序に従って、インデックス列を使用できない場合は、sort_buffer_sizeとmax_size_for_sort_dataのサイズを増やします。
- 持っているよりも高いところに書くことができる資格は持っていることで書かれるべきではありません