我在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
上的索引只会是有益的,还是我必须包含colA
和colB
?
我最终使用了这个查询,
SELECT `ColA`,`date`, `ColB`
FROM atm_status_log
WHERE `ColA` = 223
HAVING `ColB` <> 1
ORDER BY `date` DESC
LIMIT 1;
以及INDEX
,INDEX(colA, colB, date)
答案 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
中有多少不同的值?如果它只能有0
和1
,请将过滤器更改为
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)
,其列完全按照该顺序排列。该指数将是一个“覆盖”指数。