У меня есть следующий запрос в функции PHP. Он вызывается несколько раз в зависимости от ряда факторов, но даже если он выполняется только 1 раз, это занимает много времени.
SELECT `date` as dateTo
FROM table_name tbl
WHERE `colA` = 223 and `colB` <> 1
ORDER BY `date` DESC
LIMIT 1
Таблица базы данных имеет около 2 миллионов записей и 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)
Вы должны добавить индекс по дате, colA, colB.
Пожалуйста, имейте в виду, что порядок индекса имеет значение.
ALTER TABLE table_name ADD KEY index_name (date, colA, colB);
Вы должны добавить индекс для colA и colB. Это решит проблему.
Это ваш запрос:
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.
Сколько разной стоимости в colB
? Если это может иметь только 0
а также 1
затем измените фильтр на
colB = 0
и добавь это
INDEX(colA, colB, date)
(The date
должно быть последним, но A и B могут быть в любом порядке.) Только тогда все фильтрация и ORDER BY
быть обработанным INDEX
,
Если colB имеет более 2 значений, давайте немного улучшим решение Гордона:
SELECT `date` as dateTo
FROM table_name tbl
WHERE `colA` = 223
AND colB <> 1
ORDER BY `date` DESC;
с INDEX(colA, colB, date)
с колонками в том же порядке. Этот индекс будет индексом «покрытия».