sql >> データベース >  >> RDS >> Mysql

複合インデックスの左端の列のワイルドカードは、インデックスの残りの列がインデックスルックアップ(MySQL)で使用されないことを意味しますか?

    ここにあなたの質問があります。複数。それらを(「言い換えれば」で)言い換えることによって、それらは単に異なる質問です。そうすることは、必ずしもレスポンダーにとって容易になるわけではありません。それどころか。

    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 |
    +----+-------------+---------+-------+---------------+----------+---------+------+--------+--------------------------+
    


    1. MySqlトリガーでINSERT操作を中止するにはどうすればよいですか?

    2. PHPとPDOを使用して単一のMySQLプリペアドステートメントに配列を挿入する方法

    3. 非常に大きな自動インクリメントIDが必要な場合はどうなりますか?

    4. WSO2EMM-App Managementは、Appがインストールされている/インストールされていないユーザーのリストを返すことはありません