2013-02-08 95 views
1

我通過我與SugarCRM公司遇到的問題,研究一種特殊的順序,我認爲下面的測試案例描述:排序索引使用

  • 鑑於以下兩個表:

    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; 
    

    end if; end loop 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; 
    

    END IF; end loop 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 |    | 
    +----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+ 
    
  • 通過

    又一次但爲了第二張表加入:

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

我不明白爲什麼查詢2使用filesort而查詢1能夠使用索引。是否有可能遇到本文檔中描述的以下限制?

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

「你在ORDER聯接許多表和列BY並不都來自用來檢索行的第一個非恆定表(這是EXPLAIN輸出,做第一個表沒有常量連接類型。)「

+0

請問您是否可以使用預先格式化的文本標籤正確格式化?讀取SQL輸出非常困難。 – 2013-02-08 12:20:38

+0

嗯,試圖添加blockquotes,但它仍然搞亂格式化,但在那裏有一些奇怪的字符。 – 2013-02-08 12:32:10

回答

0

您已正確識別第二個查詢未使用索引的原因。

既然你從test1LEFT JOINtest2test1是用來檢索行第一非常數表,所以從test2列不能使用索引進行排序。

我不認爲有一種方法可以讓您的查詢保持相同的功能,但使用索引test2 ...但如果您要將聯接類型從left join更改爲inner join,則應該使用指數。

+0

非常感謝Michael Fredrickson。 – 2013-02-10 07:29:28