创建INDEX以改善ORDER BY导致的慢执行时间

时间:2017-08-10 10:10:54

标签: php mysql sql indexing phpmyadmin

我在PHP函数中有以下查询。根据许多因素,这会被调用多次,但即使只执行一次也需要很长时间。

SELECT  `date` as dateTo
FROM    table_name tbl
WHERE    `colA` = 223 and `colB` <> 1
ORDER BY `date` DESC
LIMIT 1

数据库表有大约200万条记录,而ORDER BY正在减慢执行时间。

在这种情况下,我可以拥有的最佳INDEX是什么?

date上的索引只会是有益的,还是我必须包含colAcolB

-----

我最终使用了这个查询,

SELECT  `ColA`,`date`, `ColB`
FROM  atm_status_log
WHERE  `ColA` = 223
HAVING  `ColB` <> 1
ORDER BY `date` DESC
LIMIT 1;

以及INDEXINDEX(colA, colB, date)

4 个答案:

答案 0 :(得分:1)

您必须为colA和colB添加索引。这将解决问题。

答案 1 :(得分:1)

这是您的查询:

SELECT `date` as dateTo
FROM table_name tbl
WHERE `colA` = 223 and `colB` <> 1
ORDER BY `date` DESC
LIMIT 1

索引的一种方法是table_name(colA, colB, date)。这是查询的覆盖索引。但是,它不会消除排序。

可以尝试这种方法:

SELECT dateTo
FROM (SELECT `date` as dateTo, colB
      FROM table_name tbl
      WHERE `colA` = 223 
      ORDER BY `date` DESC
     ) t
WHERE `colB` <> 1;

子查询应该能够在table_name(colA, date)上使用查询。它需要实现整个结果集,但是选择colB <> 1应该非常快。我对这种方法并不感到兴奋,因为它假定子查询在被外部查询读取时仍保持有序 - 但在MySQL中也是如此。

答案 2 :(得分:1)

您必须在日期,colA,colB上添加索引。 请记住索引的顺序很重要。

ALTER TABLE table_name ADD KEY index_name (date, colA, colB); 

答案 3 :(得分:1)

colB中有多少不同的值?如果它只能有01,请将过滤器更改为

colB = 0

并添加此

INDEX(colA, colB, date)

date必须是最后一个,但A和B可以是任意顺序。)只有这样,所有过滤和ORDER BY才能由INDEX处理。 / p>

如果colB的值超过2,那么让我们稍微改进一下Gordon的解决方案:

SELECT  `date` as dateTo
    FROM  table_name tbl
    WHERE  `colA` = 223
      AND   colB <> 1
    ORDER BY  `date` DESC;

使用INDEX(colA, colB, date),其列完全按照该顺序排列。该指数将是一个“覆盖”指数。