#mysql #indexing #query-optimization
#mysql #индексирование #оптимизация запросов
Вопрос:
Вот запрос, который необходимо оптимизировать:
Scans: 527676 records...
Returns: 496 records...
SELECT * FROM customers c
WHERE DATE_ADD(c.`custdate` ,INTERVAL -5 HOUR) BETWEEN '2011-09-14 00:00:00' AND '2011-09-14 23:59:59'
AND c.`custtype`='L'
Это то же самое без использования DATE_ADD:
Scans: 801 records...
Returns: 481 records...
SELECT * FROM customers c
WHERE c.`custdate` BETWEEN '2011-09-14 00:00:00' AND '2011-09-14 23:59:59'
Вопрос в том, как мне оптимизировать этот запрос с помощью функции DATE_ADD()? Без использования DATE_ADD он подбирает мои индексы, и запрос в порядке.
Ожидаю помощи по этому вопросу.
Спасибо,
Рахиль
Ответ №1:
Поскольку вы просто добавляете постоянный временной интервал c.custdate
, вместо этого следует вычесть этот временной интервал из BETWEEN
значений, чтобы получить запрос, который логически эквивалентен, но позволяет MySQL использовать индекс. В общем случае, если запрос требует вычисления функции значений индекса, сканирование диапазона не может быть использовано.
То есть: вместо WHERE
предложения, являющегося
DATE_ADD(c.`custdate` ,INTERVAL -5 HOUR) BETWEEN '2011-09-14 00:00:00' AND '2011-09-14 23:59:59'
сделайте это
c.`custdate` BETWEEN '2011-09-14 05:00:00' AND '2011-09-15 04:59:59'
Комментарии:
1. Полностью согласен — MySQL не может использовать индексы, когда вы выполняете функцию для рассматриваемого поля, поэтому всегда старайтесь выполнять функцию для критериев фильтрации, а не для поля. Затем MySQL может использовать доступные индексы
2. … кроме того, вполне возможно выполнить функцию «DATE_ADD» для каждого из значений в предложении «BETWEEN», поскольку MySQL будет оптимизировать их, где это возможно. Например. «c.
custdate
МЕЖДУ DATE_ADD (‘2011-09-14 00:00:00’ ИНТЕРВАЛ 5 ЧАСОВ) И DATE_ADD(‘2011-09-14 23:59:59’ ИНТЕРВАЛ 5 ЧАСОВ)»3. Да, это работает.. Поскольку вы предлагаете добавить 5 часов к обоим предложениям dates in between, чтобы получить аналогичные результаты по состоянию на GMT-5, знаете ли вы удобную функцию для добавления 5 часов к datetime, чтобы я мог реорганизовать все запросы, используя date_add .
4. Как вы и предлагали, теперь я использую функцию DATE_ADD в критериях, а не в поле, однако, пока я использовал интервал -5 часов в поле, теперь я использую интервал 5 часов в критериях… ВЫБЕРИТЕ * ИЗ customers c, ГДЕ c.
custdate
МЕЖДУ DATE_ADD(‘2011-09-14 00:00:00’ , ИНТЕРВАЛ 5 ЧАСОВ) И DATE_ADD(‘2011-09-14 23:59:59’ , ИНТЕРВАЛ 5 ЧАСОВ) Большое спасибо за помощь…