MySQL-explain出力情報の詳細
119449 ワード
常用SQL(テーブル名がstudentであると仮定)
接続クエリー、結合クエリー、サブクエリー:
表構造の表示:show create student;desc student;
インデックスの追加:プライマリ・キーの追加:alter table class add constraint primary key cid_pk(cid); プライマリ・キーの削除:alter table class drop primary key;インデックスの追加:alter table class add index cid_idx(cid); またはcreate index dexc_idx on class(cdesc); インデックスの削除:drop index sid on student;
テーブルのインデックスの表示:show index from student;
修正テーブルの文字コード:alter table student charset=utf 8 mb 4;フィールドタイプの変更:alter table student modify name char(30)not null;
テストデータの作成
MySQLの解析プロセス
MySQLでは、各SQL文の解析は、左から右ではなく指定された順序で行われます.from->on->join->where->groupby->having->select distinct->order by->limitの順です.たとえば、次のSQLの場合:
MySQLの解析手順は次のとおりです.クエリーするプライマリ・テーブルを先に判断する:studentテーブル 使用する接続クエリー関連フィールドを判断する:cid 接続クエリーのテーブル:classテーブル whereクエリー条件対応フィールド:s.age groupby対応フィールド:name having対応フィールド:sid クエリーするフィールド:sid order by対応フィールド:sid limit制限クエリー・バー数:5 explainの出力情報
公式ドキュメント:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
id:クエリー番号select_type:クエリータイプtable:テーブル名type:インデックスヒットタイプpossible_keys:利用可能なインデックスkey:実際に利用したインデックスkey_len:インデックス長ref:参照rows:スキャンしたデータ行数Extra:付加情報
id
SQLにサブクエリがある場合、各サブクエリはidに対応し、最内層サブクエリのidが最大で、最大のidが最初に実行されます.select t.* from class c,student s,teacher t where s.cid = c.cid and t.cid = c.cid and (s.id = 1 or s.name = ‘s2’); SQLにサブクエリがない場合、idの列は同じで、上から行ごとに実行されます.
select_type
select_typeクエリータイプ simple:単純なクエリー、SQLにサブクエリーとunion はありません. primary:プライマリ・クエリー、SQLにサブクエリーまたはunionがある場合の最外層クエリーがプライマリ・クエリー です. subquery:内層サブクエリ、SQLにサブクエリがある場合は最外層クエリを除いて union:共同クエリー union result:クエリーを統合するときのヒント情報.どのテーブル であるかを示します. derived:派生クエリー、クエリー中にテンポラリ・テーブルが使用され、2つの状況に分けられます. fromの後ろにサブクエリがあり、1枚のテーブルしかありません.例えば、 を表しています. fromの後ろにサブクエリがあり、unionを使用して複数のテーブルを結合する場合、左のテーブルは派生クエリであり、右のテーブルは連合クエリであり、例えば: dependent subquery:外部のプライマリ・クエリー依存サブクエリー、たとえば dependent union:サブクエリは連合クエリであり、外部のプライマリクエリはサブクエリに依存し、 select_type SQLの例
simple
primary
unionとunion resultの場合
サブクエリの場合
subquery
dependent subqueryとdependent unionの場合
derived
fromの後ろにサブクエリがあり、テーブルが1つしかありません.
fromの後ろにサブクエリがあり、unionを使用して複数のテーブルを結合する場合、左のテーブルは派生クエリ、右のテーブルは連合クエリ
type
インデックスがない場合やインデックスが使用されていない場合は、すべてのデータをフルスキャンする必要があります.インデックスにヒットすると、さまざまな効果の違いがあります.
MySQLのインデックス、効果は良いから悪いまで並べ替えます:system>const>eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery>range>index>ALLは一般的に、クエリが少なくともrangeレベルに達することを保証し、refに達することが望ましい.
タイプの説明 ALL:Full Table Scan、インデックスなし、全テーブルスキャン. index:Full Index Scan、indexタイプはインデックスツリーのみを巡回します. range:インデックスツリーで範囲スキャンのみ.key列には、どのインデックスが使用されているかが表示されます.対応するオペレータには、=、<>、>=、、BETWEENまたはINオペレータがあります.ここで、INは全テーブルスキャンALLに劣化する可能性がある. ref:一意でないインデックスアクセスで、単一の値に一致するすべてのローを返します.非一意インデックスまたは一意インデックスの非一意接頭辞を使用する場合にのみ発生します. eq_ref:一意のインデックスアクセス.最大1つの条件を満たすレコードのみが返されます.マルチテーブル接続ではprimary keyまたはunique keyを関連条件として使用します. const:where条件でプライマリ・キーまたはunique一意キーを使用する場合、テーブルに一致するローは最大1つのみです. system:クエリーするテーブル(プライマリ・テーブルまたは派生テーブル)には1行のデータしかありません. Null:mysqlは、最適化フェーズでクエリー文を分解し、実行フェーズではアクセステーブルやインデックスさえ使用できません.
type SQLの例
system
クエリーするテーブル(プライマリ・テーブルまたは派生テーブル)には、1行のデータしかありません.
const
プライマリ・キーまたはユニーク・キーをwhere条件として使用します.
eq_ref
プライマリ・キーを使用して関連条件を設定すると、次のような効果が得られます.
ref
ユニークでないインデックスの場合、where条件として使用すると、typeタイプがrefの場合、複数のローがヒットする可能性があります.
range
index
インデックスデータをフルスキャンします.
All
テーブルのデータをフルスキャンします.
possible_keys
MySQLオプティマイザは、使用可能なインデックスを判断し、実際には必ずしも使用しない.
key
実際に利用したインデックス.NULLではインデックスは使用されません.
key_len
where条件でインデックスに使用されるバイト数.通常、複合インデックスがいくつかのフィールドにヒットしたかを判断するために使用されます.MySQLでは、文字列の場合、utf 8は1文字あたり3バイト、utf 8_mb 4は1文字あたり4バイトを占めます. NULLを許可するフィールドには、1バイト追加する必要があります.例えばintタイプインデックスでnullが許可されていない場合key_len=4、nullが許可されている場合key_len = 5. varcharが長くなる文字列には、2バイト追加する必要があります.
まず、テストテーブルとテストデータを作成します.
次にクエリーするデータとwhere条件は同じインデックスで、フルインデックスデータをスキャンする必要があります.また、インデックスフィールドはnullでもよいのでkey_len = (4 + 1) * 3 = 15:
以下では、インデックスに一致する最初のフィールドのみを使用します.
charおよびvarcharタイプ、nullを許可するかどうかの例は、次のとおりです.
utf 8 mb 4符号化フォーマット:
ref
インデックス・カラムの値を検索するために使用されるカラムまたは定数.たとえば、
rows
スキャンされたデータの行数.推定値
Extra:追加情報 Using filesort:追加のソート操作が必要で、できるだけ避ける必要があります.ソート操作によく使用されます. 単一フィールドインデックスは、ソートと検索が同じフィールドでない場合に表示されます. コンビネーションインデックスは、最左接頭辞の原則を満たさない場合にも表示されます.
Using index:インデックスが上書きされ、クエリーするデータがインデックスに含まれ、パフォーマンスが向上します. Using where:インデックス部分が上書きされ、テーブルクエリに戻る必要があります. Using temporary:結果セットを格納するためにテンポラリ・テーブルを使用する必要があります.パケット・クエリーでは、できるだけ避ける必要があります. Using join buffer:値を変更すると、接続条件を取得する際にインデックスが使用されず、中間結果を格納するためにバッファに接続する必要があることが強調されます.この値が表示された場合、クエリの状況に応じてインデックスを追加してエネルギーを改善する必要がある場合があることに注意してください. Impossible WHERE:where文は、 Selecttables optimized away:この値は、インデックスのみを使用することによって、オプティマイザが集約関数の結果から1行 だけを返すことを意味します.
Using filesort
インデックスなしのフィールド、where条件ではないインデックスフィールド、コンビネーションインデックスがありますがヒットしません.この3つの場合、order byソートを行うと、ソート操作が複数回行われます.まず、テストテーブルとテストデータを作成します.
単一カラムインデックスの場合、order byのフィールドがwhere条件にすでに表示されている場合、filesortは表示されません.
結合インデックスの場合、結合インデックスの接頭辞を一致させる必要があります.そうしないとfilesortが表示されます.
Using index
クエリーするデータとwhere条件がインデックスにヒットし、効率が高い:
接続クエリー、結合クエリー、サブクエリー:
表構造の表示:show create student;desc student;
インデックスの追加:プライマリ・キーの追加:alter table class add constraint primary key cid_pk(cid); プライマリ・キーの削除:alter table class drop primary key;インデックスの追加:alter table class add index cid_idx(cid); またはcreate index dexc_idx on class(cdesc); インデックスの削除:drop index sid on student;
テーブルのインデックスの表示:show index from student;
修正テーブルの文字コード:alter table student charset=utf 8 mb 4;フィールドタイプの変更:alter table student modify name char(30)not null;
テストデータの作成
create table class(
cid int(10),
cdesc varchar(20)
);
create table student(
sid int(10),
name varchar(20),
age int(3),
cid int(10)
);
create table teacher(
tid int(10),
name varchar(20),
cid int(10)
);
insert into class values(1, "PHP"),(2, "Java"),(3, "C++"),(4,"SQL");
insert into student values(1, "s1",16,1),(2, "s2",17,2),(3, "s3",18,3),(4,"s4",19,4),(5, "s5",18,3),(6,"s6",19,4);
insert into teacher values(1, "t1",1),(2, "t2",2),(3, "t3",3),(4,"t4",4);
alter table student add constraint sid_pk primary key(sid);
MySQLの解析プロセス
MySQLでは、各SQL文の解析は、左から右ではなく指定された順序で行われます.from->on->join->where->groupby->having->select distinct->order by->limitの順です.たとえば、次のSQLの場合:
select distinct sid from student s left join class c on s.cid = c.cid where s.age = 19 group by name having sid > 4 order by sid desc limit 5;
MySQLの解析手順は次のとおりです.
公式ドキュメント:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
mysql> explain select * from s2;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | s2 | ALL | NULL | NULL | NULL | NULL | 64 | |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
id:クエリー番号select_type:クエリータイプtable:テーブル名type:インデックスヒットタイプpossible_keys:利用可能なインデックスkey:実際に利用したインデックスkey_len:インデックス長ref:参照rows:スキャンしたデータ行数Extra:付加情報
id
SQLにサブクエリがある場合、各サブクエリはidに対応し、最内層サブクエリのidが最大で、最大のidが最初に実行されます.select t.* from class c,student s,teacher t where s.cid = c.cid and t.cid = c.cid and (s.id = 1 or s.name = ‘s2’); SQLにサブクエリがない場合、idの列は同じで、上から行ごとに実行されます.
select_type
select_typeクエリータイプ
select s.name from (select * from student where sid < 5) s;
、下図のtable列のderived 2が派生テーブルで、数字2はid列の値select * from (select * from student where sid < 2 union select * from student where sid > 2) s;
explain select * from student where sid in (select sid from student where sid > 3);
explain select * from student where sid in (select sid from student where sid < 2 union select sid from student where sid > 2);
simple
mysql> explain select * from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 6 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
primary
unionとunion resultの場合
mysql> explain select * from student where sid < 2 union select * from student where sid > 2;
+----+--------------+------------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+-------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | student | range | sid | sid | 5 | NULL | 1 | Using where |
| 2 | UNION | student | ALL | sid | NULL | NULL | NULL | 6 | Using where |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------+------------+-------+---------------+------+---------+------+------+-------------+
3 rows in set (0.00 sec)
サブクエリの場合
mysql> explain select * from student where sid in (select sid from student where sid > 3);
+----+--------------------+---------+----------------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+----------------+---------------+------+---------+------+------+--------------------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| 2 | DEPENDENT SUBQUERY | student | index_subquery | sid | sid | 5 | func | 1 | Using index; Using where |
+----+--------------------+---------+----------------+---------------+------+---------+------+------+--------------------------+
2 rows in set (0.02 sec)
subquery
mysql> explain select * from student where sid > (select sid from student where name = 's3');
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | student | ALL | sid | NULL | NULL | NULL | 6 | Using where |
| 2 | SUBQUERY | student | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.00 sec)
dependent subqueryとdependent unionの場合
mysql> explain select * from student where sid in (select sid from student where sid < 2 union select sid from student wher
+----+--------------------+------------+------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+------+---------------+------+---------+------+------+--------------------------+
| 1 | PRIMARY | student | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| 2 | DEPENDENT SUBQUERY | student | ref | sid | sid | 5 | func | 1 | Using where; Using index |
| 3 | DEPENDENT UNION | student | ref | sid | sid | 5 | func | 1 | Using where; Using index |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------------+------------+------+---------------+------+---------+------+------+--------------------------+
4 rows in set (0.00 sec)
derived
fromの後ろにサブクエリがあり、テーブルが1つしかありません.
mysql> explain select s.name from (select * from student where sid < 5) s;
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 4 | |
| 2 | DERIVED | student | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.00 sec)
fromの後ろにサブクエリがあり、unionを使用して複数のテーブルを結合する場合、左のテーブルは派生クエリ、右のテーブルは連合クエリ
mysql> explain select * from (select * from student where sid < 2 union select * from student where sid > 2) s;
+----+--------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 5 | |
| 2 | DERIVED | student | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| 3 | UNION | student | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------+------------+------+---------------+------+---------+------+------+-------------+
type
インデックスがない場合やインデックスが使用されていない場合は、すべてのデータをフルスキャンする必要があります.インデックスにヒットすると、さまざまな効果の違いがあります.
MySQLのインデックス、効果は良いから悪いまで並べ替えます:system>const>eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery>range>index>ALLは一般的に、クエリが少なくともrangeレベルに達することを保証し、refに達することが望ましい.
タイプの説明
type SQLの例
system
クエリーするテーブル(プライマリ・テーブルまたは派生テーブル)には、1行のデータしかありません.
mysql> select * from s1;
+-----+------+------+------+
| sid | name | age | cid |
+-----+------+------+------+
| 1 | s1 | 22 | 1 |
+-----+------+------+------+
1 row in set (0.00 sec)
mysql> explain select * from (select * from s1) s where sid = 1;
+----+-------------+------------+--------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+------+---------+------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | s1 | ALL | NULL | NULL | NULL | NULL | 1 | |
+----+-------------+------------+--------+---------------+------+---------+------+------+-------+
2 rows in set (0.00 sec)
const
プライマリ・キーまたはユニーク・キーをwhere条件として使用します.
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`sid` int(10) NOT NULL DEFAULT '0',
`name` varchar(20) DEFAULT NULL,
`age` int(3) DEFAULT NULL,
`cid` int(10) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> explain select * from student where sid = 3;
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | student | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)
eq_ref
プライマリ・キーを使用して関連条件を設定すると、次のような効果が得られます.
mysql> alter table class add constraint primary key cid_pk(cid);
Query OK, 4 rows affected (0.23 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> explain select * from student s left join class c on s.cid = c.cid where s.sid = 3;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | s | const | PRIMARY | PRIMARY | 4 | const | 1 | |
| 1 | SIMPLE | c | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
2 rows in set (0.00 sec)
ref
ユニークでないインデックスの場合、where条件として使用すると、typeタイプがrefの場合、複数のローがヒットする可能性があります.
mysql> alter table student add index name_idx(name);
mysql> explain select * from student where name = 's3';
+----+-------------+---------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+----------+---------+-------+------+-------------+
| 1 | SIMPLE | student | ref | name_idx | name_idx | 23 | const | 1 | Using where |
+----+-------------+---------+------+---------------+----------+---------+-------+------+-------------+
1 row in set (0.00 sec)
range
mysql> explain select * from student where name like 's3';
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | student | range | name_idx | name_idx | 23 | NULL | 1 | Using where |
+----+-------------+---------+-------+---------------+----------+---------+------+------+-------------+
1 row in set (0.00 sec)
index
インデックスデータをフルスキャンします.
mysql> explain select sid from student;
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | student | index | NULL | PRIMARY | 4 | NULL | 6 | Using index |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
All
テーブルのデータをフルスキャンします.
mysql> explain select * from student;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | student | ALL | NULL | NULL | NULL | NULL | 6 | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
possible_keys
MySQLオプティマイザは、使用可能なインデックスを判断し、実際には必ずしも使用しない.
key
実際に利用したインデックス.NULLではインデックスは使用されません.
key_len
where条件でインデックスに使用されるバイト数.通常、複合インデックスがいくつかのフィールドにヒットしたかを判断するために使用されます.MySQLでは、文字列の場合、utf 8は1文字あたり3バイト、utf 8_mb 4は1文字あたり4バイトを占めます.
まず、テストテーブルとテストデータを作成します.
create table filesort (
f1 int(10),
f2 int(10),
f3 int(10),
f4 int(10),
index idx_f4(f4),
index idx_f1_f2_f3(f1, f2, f3)
);
insert into filesort values(1, 2, 3, 4),(11, 12, 13, 14), (21, 22, 23, 24);
次にクエリーするデータとwhere条件は同じインデックスで、フルインデックスデータをスキャンする必要があります.また、インデックスフィールドはnullでもよいのでkey_len = (4 + 1) * 3 = 15:
mysql> explain select f2 from filesort where f3 = 3;
+----+-------------+----------+-------+---------------+--------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+--------------+---------+------+------+--------------------------+
| 1 | SIMPLE | filesort | index | NULL | idx_f1_f2_f3 | 15 | NULL | 3 | Using where; Using index |
+----+-------------+----------+-------+---------------+--------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
以下では、インデックスに一致する最初のフィールドのみを使用します.
mysql> explain select f2 from filesort where f1 = 3;
+----+-------------+----------+------+---------------+--------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | filesort | ref | idx_f1_f2_f3 | idx_f1_f2_f3 | 5 | const | 1 | Using where; Using index |
+----+-------------+----------+------+---------------+--------------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)
charおよびvarcharタイプ、nullを許可するかどうかの例は、次のとおりです.
mysql> alter table filesort modify f4 varchar(30);
Query OK, 3 rows affected (2.24 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> explain select f2,f4 from filesort where f4 = '';
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| 1 | SIMPLE | filesort | ref | idx_f4 | idx_f4 | 93 | const | 1 | Using where |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
1 row in set (0.00 sec)
mysql> alter table filesort modify f4 char(30) not null;
Query OK, 3 rows affected (2.03 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> explain select f2,f4 from filesort where f4 = '';
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| 1 | SIMPLE | filesort | ref | idx_f4 | idx_f4 | 90 | const | 1 | Using where |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
1 row in set (0.00 sec)
utf 8 mb 4符号化フォーマット:
mysql> alter table filesort charset = utf8mb4;
Query OK, 3 rows affected (2.08 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> alter table filesort modify f4 char(30) not null;
Query OK, 3 rows affected (0.25 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> explain select f2,f4 from filesort where f4 = '';
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| 1 | SIMPLE | filesort | ref | idx_f4 | idx_f4 | 120 | const | 1 | Using where |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
1 row in set (0.00 sec)
ref
インデックス・カラムの値を検索するために使用されるカラムまたは定数.たとえば、
where t1.id = t2.key
は他のテーブルのインデックスを関連付け、where id = 3
はconst定数を使用します.mysql> explain select * from student where sid = 3;
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | student | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> alter table class add index idx_cid(cid);
Query OK, 0 rows affected (1.97 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select * from student s,class c where s.cid = c.cid;
+----+-------------+-------+------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+------------+------+-------------+
| 1 | SIMPLE | s | ALL | NULL | NULL | NULL | NULL | 6 | |
| 1 | SIMPLE | c | ref | idx_cid | idx_cid | 5 | test.s.cid | 1 | Using where |
+----+-------------+-------+------+---------------+---------+---------+------------+------+-------------+
2 rows in set (0.00 sec)
rows
スキャンされたデータの行数.推定値
Extra:追加情報
where f1 = 3 and f1 = 4
などの条件に合致しない行をもたらします.Using filesort
インデックスなしのフィールド、where条件ではないインデックスフィールド、コンビネーションインデックスがありますがヒットしません.この3つの場合、order byソートを行うと、ソート操作が複数回行われます.まず、テストテーブルとテストデータを作成します.
create table filesort (
f1 int(10),
f2 int(10),
f3 int(10),
f4 int(10),
index idx_f4(f4),
index idx_f1_f2_f3(f1, f2, f3)
);
insert into filesort values(1, 2, 3, 4),(11, 12, 13, 14), (21, 22, 23, 24);
単一カラムインデックスの場合、order byのフィールドがwhere条件にすでに表示されている場合、filesortは表示されません.
mysql> explain select * from filesort where f4 = 1 order by f4;
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
| 1 | SIMPLE | filesort | ref | idx_f4 | idx_f4 | 5 | const | 1 | Using where |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from filesort where f4 = 1 order by f3;
+----+-------------+----------+------+---------------+--------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | filesort | ref | idx_f4 | idx_f4 | 5 | const | 1 | Using where; Using filesort |
+----+-------------+----------+------+---------------+--------+---------+-------+------+-----------------------------+
1 row in set (0.00 sec)
結合インデックスの場合、結合インデックスの接頭辞を一致させる必要があります.そうしないとfilesortが表示されます.
mysql> explain select * from filesort where f1 = 1 and f2 = 2 order by f3;
+----+-------------+----------+------+---------------+--------------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------------+---------+-------------+------+-------------+
| 1 | SIMPLE | filesort | ref | idx_f1_f2_f3 | idx_f1_f2_f3 | 10 | const,const | 1 | Using where |
+----+-------------+----------+------+---------------+--------------+---------+-------------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from filesort where f1 = 1 order by f3;
+----+-------------+----------+------+---------------+--------------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | filesort | ref | idx_f1_f2_f3 | idx_f1_f2_f3 | 5 | const | 1 | Using where; Using filesort |
+----+-------------+----------+------+---------------+--------------+---------+-------+------+-----------------------------+
1 row in set (0.00 sec)
Using index
クエリーするデータとwhere条件がインデックスにヒットし、効率が高い:
mysql> explain select f2 from filesort where f3 = 3;
+----+-------------+----------+-------+---------------+--------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+--------------+---------+------+------+--------------------------+
| 1 | SIMPLE | filesort | index | NULL | idx_f1_f2_f3 | 15 | NULL | 3 | Using where; Using index |
+----+-------------+----------+-------+---------------+--------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
mysql> explain select f2 from filesort where f1 = 3;
+----+-------------+----------+------+---------------+--------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+--------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | filesort | ref | idx_f1_f2_f3 | idx_f1_f2_f3 | 5 | const | 1 | Using where; Using index |
+----+-------------+----------+------+---------------+--------------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)