ここにあなたの質問があります。複数。それらを(「言い換えれば」で)言い換えることによって、それらは単に異なる質問です。そうすることは、必ずしもレスポンダーにとって容易になるわけではありません。それどころか。
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としてそれがアプリケーションにとって恐ろしい理由はおそらく12あります。
以下の元の回答:
のみ (last_name,first_name)
の複合キー そしてあなたが言及するような質問
WHERE first_name LIKE 'joh%'
...インデックスはまったく使用されません。テーブルスキャンを実行します。不在のため
-
first_name
の単一列キー -
first_name
の複合キー 左端
テーブルスキャンがここにあります。
マニュアルページleft-most
に焦点を当てます それの概念。実際、そのページに移動して、left
という単語を検索してください。 。
説明 のマニュアルページを参照してください。 mysqlの機能。また、記事Explainを使用してより良いMysqlクエリを作成する 。
編集
私が1、2時間前にここにいたので、質問にいくつかの編集がありました。以下を残しておきます。 Explainを介して実際のクエリを実行し、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 |
+----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+