我正在通过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,并在连接的第一个表中执行订单:
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输出中没有const连接类型的第一个表。)“
答案 0 :(得分:0)
您已正确识别第二个查询未使用索引的原因。
由于您从LEFT JOIN
到test1
执行了test2
,test1
是第一个用于检索行的非常量表 ,因此无法使用索引对test2
中的列进行排序。
我认为您的查询无法在功能上保持相同但使用test2
的索引...但是如果您要将联接类型从left join
更改为{{ 1}},它应该使用索引。