【问题标题】:Query optimization with number of tables join and order by with limit clause使用限制子句连接和排序的表数进行查询优化
【发布时间】:2011-07-01 05:57:42
【问题描述】:

我有一个查询,它使用 distincct - left join - 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;

在代码中使用的所有列都有索引。这个查询的 explan 输出给出了结果集,我可以看到它正确使用了所有索引,它从所有表中扫描的总行数为 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 子句中使用的列上有一个复合索引。我还尝试在此列上创建单个索引,但没有任何效果。

【问题讨论】:

  • 表格有多少行?如果您提供了有序查询的执行计划,将会有所帮助。以及表的结构(PK、FK)和现有索引。
  • 大多数表中都有数百万行。我会得到解释的输出并把它放在这里。谢谢

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


【解决方案1】:

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

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

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

我不确定是否有解决方法。这取决于表结构和实际查询。

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

【讨论】:

    【解决方案2】:

    我会先尝试在以下位置添加复合索引:

    Table a
        (col2, col1)
    
    Table b
        (col4, col1)
    

    和一个简单的索引

    Table h
        (col5)
    

    【讨论】:

      猜你喜欢
      • 2015-02-25
      • 1970-01-01
      • 1970-01-01
      • 2019-12-15
      • 2012-05-11
      • 2017-03-08
      • 2017-01-10
      • 2020-03-19
      • 2010-11-06
      相关资源
      最近更新 更多