1

私はSugarCRMで遭遇した問題ごとに特定の順序を調査しています。これは、次のテストケースで説明されていると思います。

  • 次の2つのテーブルがあるとします。

      CREATE TABLE test1 (
      id int(11) NOT NULL AUTO_INCREMENT,
      name char(20),
      PRIMARY KEY (id)
      );
    
    CREATE TABLE test2 (
    id int(11) NOT NULL AUTO_INCREMENT,
     name char(20),
     name2 varchar(10),
     PRIMARY KEY (id)
    );
    
  • テーブルtest1にランダムデータを挿入します。

     delimiter $$  
     create procedure randomizer()
     begin
     declare i int Default 0 ;
     declare random char(20) ;
     declare random2 char(10) ;
     myloop: loop
     set random=conv(floor(rand() * 99999999999999), 20, 36) ;
     insert into test1 (id, name) VALUES (i+1,random) ;
     set i=i+1;
     if i=1000 then
      leave myloop;
    

    次の場合に終了します。ループmyloopを終了します。$$区切り文字を終了します;

  • テーブルtest2にランダムデータを挿入します。

     delimiter $$  
     create procedure randomizer()
     begin
     declare i int Default 0 ;
     declare random char(20) ;
     declare random2 char(10) ;
     myloop: loop
     set random=conv(floor(rand() * 99999999999999), 20, 36) ;
     set random2=conv(floor(rand() * 999999), 10, 36) ;
     insert into test2 (id, name, name2) VALUES (i+1,random, random2) ;
     set i=i+1;
     if i=1000 then
     leave myloop;
    

    次の場合に終了します。ループmyloopを終了します。$$区切り文字を終了します;

  • セカンダリインデックスを追加します。

         alter table test1 add index(name);
    
         alter table test2 add index(name);
    
  • 結合の最初のテーブルで順序付きのテーブル結合を使用してQEPを実行します。

    explain select test1.name, test2.name from test1 left join test2 on test1.id=test2.id order by test1.name
    
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
    | id | select_type | table |  type  | possible_keys |   key   | key_len |      ref      | rows |    Extra    |
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
    |  1 | SIMPLE      | test1 | index  | NULL          | name    |      21 | NULL          |  981 | Using index |
    |  1 | SIMPLE      | test2 | eq_ref | PRIMARY       | PRIMARY |       4 | test.test1.id |    1 |             |
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
    
  • また、結合の2番目のテーブルで並べ替えます。

    explain select test1.name, test2.name from test1 left join test2 on test1.id=test2.id order by test2.name
    
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+----------------------------------------------+
    | id | select_type | table |  type  | possible_keys |   key   | key_len |      ref      | rows |                    Extra                     |
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+----------------------------------------------+
    |  1 | SIMPLE      | test1 | index  | NULL          | name    |      21 | NULL          |  981 | Using index; Using temporary; Using filesort |
    |  1 | SIMPLE      | test2 | eq_ref | PRIMARY       | PRIMARY |       4 | test.test1.id |    1 |                                              |
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+----------------------------------------------+
    

クエリ1がインデックスを使用できるのに、クエリ2がファイルソートを使用する理由がわかりません。このドキュメントで説明されている次の制限に遭遇する可能性はありますか?

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

「多くのテーブルを結合していますが、ORDER BYの列はすべて、行の取得に使用される最初の非定数テーブルからのものではありません(これは、const結合タイプを持たないEXPLAIN出力の最初のテーブルです)。」

4

1 に答える 1

0

2番目のクエリがインデックスを使用していない理由を正しく特定しました。

LEFT JOINfrom test1toを実行したので、は行を取得するために使用される最初の非定数テーブルtest2であるため、からの列はインデックスを使用して並べ替えることができません。test1test2

クエリが機能的に同じを維持する方法はないと思いますが、test2...のインデックスを使用します。ただし、結合タイプをからに変更するleft join場合inner joinは、インデックスを使用する必要があります。

于 2013-02-08T16:05:08.813 に答える