【问题标题】:Order by index usage按索引使用排序
【发布时间】:2013-02-09 00:05:08
【问题描述】:

我正在研究我在 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;
    

    结束如果; 结束循环 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,并在连接中的第一个表上使用 order by:

    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 使用文件排序,而查询 1 能够使用索引。我是否可能遇到本文档中描述的以下限制?

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

“您正在连接许多表,并且 ORDER BY 中的列并非全部来自用于检索行的第一个非常量表。(这是 EXPLAIN 输出中没有 const 连接类型的第一个表.)"

【问题讨论】:

  • 能否请您正确格式化它,也许使用预先格式化的文本标签?读取 SQL 输出非常困难。
  • 嗯,尝试添加块引号,但它仍然弄乱了格式,但有一些奇怪的字符。

标签: mysql sql-order-by sugarcrm


【解决方案1】:

您已正确识别出第二个查询未使用索引的原因。

由于您已经执行了从 test1 到 test2 的 LEFT JOIN,test1 是第一个用于检索行的非常量表,因此来自 test2 的列无法使用索引进行排序。

我认为没有办法让您的查询在功能上保持相同,但使用test2 的索引...但是如果您要将连接类型从left join 更改为inner join,它应该然后利用索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2016-02-15
    • 2020-04-30
    • 2020-02-07
    • 2018-08-29
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    相关资源
    最近更新 更多