ここにあなたの質問があります。複数。それらを(「言い換えれば」で)言い換えると、それらは単なる異なる質問です。そうすることで、レスポンダーが必ずしも簡単になるわけではありません。それどころか。
Q1: [タイトルの質問] 複合インデックスの一番左の列のワイルドカードは、インデックスの残りの列がインデックス ルックアップ (MySQL) で使用されないことを意味しますか?
A1: いいえ、そうではありません。
Q2: last_name 条件で使用されるワイルドカードは、MySQL がインデックスを見つけるのをさらに支援するために first_name 条件が使用されないことを意味しますか?
A2: いいえ、そうではありません。さらに、その質問の末尾はあいまいです。使用するインデックスが、そのような曖昧さに対する 1 つの派生的な答えになる可能性があることは既にわかっています。
Q3: つまり、last_name 条件にワイルドカードを配置すると、MySQL は部分的なインデックス ルックアップのみを実行します (そして、last_name の右側にある列に指定された条件を無視します)?
A3: いいえ。最も右側の列は、データ ページ ルックアップの遅さから恩恵を受けるカバリング インデックス戦略と同様に、インデックスから提供されます。
Q4: ...例 1 は例 2 よりも高速ですか?
A4: はい。それらの列に関するカバーインデックスです。カバリング インデックスを参照してください。
Q4について余談ですが。PK か非 PK かは関係ありません。PK がアプリケーションにとって恐ろしいものになる理由は、おそらく十数個あります。
以下の元の回答:
あなたが言及したように、複合キーと
クエリのみを使用して(last_name,first_name)
WHERE first_name LIKE 'joh%'
... インデックスをまったく使用しません。テーブルスキャンを実行します。不在のため、
- の単一列キー
first_name
- 一番左の複合キー
first_name
それでは、テーブルスキャンを始めましょう。
詳細については、マニュアル ページの複数列インデックスを参照してください。left-most
そして、そのコンセプトに焦点を当てます。実際、そのページに移動し、単語を検索してくださいleft
。
mysqlのExplain機能に関するマニュアル ページを参照してください。また、記事Using Explain to Write Better Mysql Queriesも参照してください。
編集
1、2 時間前にここに来てから、質問にいくつかの編集がありました。以下に残します。説明を通じて実際のクエリを実行し、Using Explain ...
上記のリンクまたは別の参照を通じて解読します
drop table myNames;
create table myNames
( id int auto_increment primary key,
lastname varchar(100) not null,
firstname varchar(100) not null,
col4 int not null,
key(lastname,firstname)
);
truncate table myNames;
insert myNames (lastName,firstName,col4) values
('Smith','John',1),('Smithers','JohnSomeone',1),('Smith3','John4324',1),('Smi','Jonathan',1),('Smith123x$FA','Joh',1),('Smi3jfif','jkdid',1),('r3','fe2',1);
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
insert myNames (lastName,firstName,col4) select lastname,firstname,col4 from mynames;
select count(*) from myNames;
-- 458k rows
select count(*)
from myNames
where lastname like 'smi%';
-- 393216 rows
select count(*)
from myNames
where lastname like 'smi%' and firstname like 'joh%';
-- 262144 rows
Explain
のブードゥー教の数字をレンダリングしrows
ます。ブードゥー?はい、クエリは 1 時間実行される可能性があるためexplain
、ファジー カウントを実行するのではなく、2 秒以内にその答えを返すように求めています。なしで実際に実行する場合、これらを基準の実際のカウント # と見なさないでくださいexplain
。
explain
select count(*)
from myNames
where lastname like 'smi%';
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| 1 | SIMPLE | myNames | range | lastname | lastname | 302 | NULL | 233627 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
explain
select count(*)
from myNames
where lastname like 'smi%' and firstname like 'joh%' and col4=1;
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| 1 | SIMPLE | myNames | range | lastname | lastname | 604 | NULL | 233627 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
-- the below chunk is interest. Look at the Extra column
explain
select count(*)
from myNames
where lastname like 'smi%' and firstname like 'joh%' and col4=1;
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | myNames | ALL | lastname | NULL | NULL | NULL | 457932 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+--------+-------------+
explain
select count(*)
from myNames
where firstname like 'joh%';
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| 1 | SIMPLE | myNames | index | NULL | lastname | 604 | NULL | 453601 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
analyze table myNames;
+----------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------------+---------+----------+----------+
| so_gibberish.mynames | analyze | status | OK |
+----------------------+---------+----------+----------+
select count(*)
from myNames where left(lastname,3)='smi';
-- 393216 -- the REAL #
select count(*)
from myNames where left(lastname,3)='smi' and left(firstname,3)='joh';
-- 262144 -- the REAL #
explain
select lastname,firstname
from myNames
where lastname like 'smi%' and firstname like 'joh%';
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
| 1 | SIMPLE | myNames | range | lastname | lastname | 604 | NULL | 226800 | Using where; Using index |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+