具有表数的查询优化连接和带限制子句的顺序

时间:2011-07-01 05:57:43

标签: mysql sql-order-by distinct limit resultset

我有一个查询,其中有多个表使用distincct连接 - 左连接 - order by - limit子句。

查询如下所示: -

Select DISTINCT a.col1, b.col2, c.col3, d.col4, e.col5, f.col6, g.col7, h.col8, 
i.col9, j.col10
From test_a a 
left join test_b b on a.col1 = b.col2 
left join test_c c on c.col1 = d.col2 
left join test_d d on d.col1 = c.col2 
left join test_e e on e.col1 = d.col2 
left join test_f f on f.col1 = e.col2 
left join test_g g on g.col1 = f.col2 
left join test_h h on h.col1 = a.col1 
left join test_i i on i.col1 = f.col2 
left join test_j j on j.col1 = i.col2
Where a.col2 = 'Y' 
and c.col4  = 1
Order by h.col5 desc 
limit 50;

所有列中使用的编码都有索引。并且该查询的解释输出给出了结果集,我可以看到它正确地使用了所有索引,并且从所有表中扫描的总行数是18000。

我在这个查询中想知道的是。如果我没有order by子句运行它,它会在几秒钟内运行。类似的东西:

Select DISTINCT a.col1, b.col2, c.col3, d.col4, e.col5, f.col6, g.col7, h.col8, 
i.col9, j.col10
From test_a a 
left join test_b b on a.col1 = b.col2 
left join test_c c on c.col1 = d.col2 
left join test_d d on d.col1 = c.col2 
left join test_e e on e.col1 = d.col2 
left join test_f f on f.col1 = e.col2 
left join test_g g on g.col1 = f.col2 
left join test_h h on h.col1 = a.col1 
left join test_i i on i.col1 = f.col2 
left join test_j j on j.col1 = i.col2
Where a.col2 = 'Y' 
and c.col4  = 1
limit 50;

如果我使用order by子句运行它,则需要30-40秒才能执行。

我尝试使用mysql:- USE INDEX FOR ORDER BY (idx_h_col5)提供的索引提示功能,但是在执行此查询时出现语法错误。错误消息显示

附近的语法不正确

我在order by子句中使用的列上有一个复合索引。我也尝试在这个列上创建一个索引,但没有什么真正有效。

2 个答案:

答案 0 :(得分:1)

MySQL可以使用键进行排序,而不是在获取数据后对结果进行排序,但仅限于满足多个条件。 您可以在此处查看这些条件的列表:http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

在您的情况下,我认为多个JOIN会阻止快速排序。其中一个提到的MySQL不能使用索引进行排序的情况是:

  

你正在加入很多桌子,而且   ORDER BY中的列不是全部   来自第一个非常数表   用于检索行。 (这是   EXPLAIN输出中的第一个表   没有const连接类型。)

我不确定是否有办法绕过它。它取决于表结构和实际查询。

要获得更多帮助,请尝试发布有序查询的解释输出。

答案 1 :(得分:0)

我首先尝试在上面添加复合索引:

Table a
    (col2, col1)

Table b
    (col4, col1)

上的简单索引
Table h
    (col5)