SQL выберите DATE в WHERE, что быстрее? - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть запрос из таблицы строк, где находится столбец datetime с указанием только года и месяца. День всегда 01, а время 00: 00: 00

При выборе данных с помощью запроса php, что быстрее?

$date = "2020-04";
$query = "SELECT * FROM table WHERE datum LIKE ?",$date ;

или

$date = "2020-04";
$rok = substr($mesic,0,4);
$mesic = substr($mesic,5,2);
$query = "SELECT * FROM table WHERE YEAR(datum) = ? AND MONTH(datum) = ?",$rok,$mesic; 

Таблица содержит 100 тысяч строк

Ответы [ 3 ]

0 голосов
/ 21 апреля 2020

У нас всегда было правило:

«Избегать функций в предложении WHERE».

Исходная информация заключается в том, что сервер базы данных должен создать таблицу Сканирование для расчета результата функции для каждой строки (даже если это только таблица ключей). Поэтому он не может эффективно использовать ключи!

НРАВИТСЯ быстрее! Если вы используете начало ключа (как вы пишете), он также может использовать его эффективно.

0 голосов
/ 21 апреля 2020

Ни. В обоих случаях у вас есть вызов функции в столбце datum. С YEAR() и MONTH() это очевидно. С LIKE вы конвертируете в строку. Оба препятствуют оптимизации и предотвращают использование индексов.

Правильная структура будет выглядеть следующим образом:

where datum >= ? and
      datum < ? + interval 1 month  -- syntax might vary depending on the database

, где ? - это заполнители параметров на начало месяца. Я бы посоветовал вам создать это в приложении как константу даты или строковую константу канонической формы YYYY-MM-DD.

0 голосов
/ 21 апреля 2020

Я бы порекомендовал:

$date = "2020-04";
$sql = "SELECT * FROM table WHERE datum = concat(?, '-01')", $date;

Основная идея состоит не в том, чтобы не применять функции (либо функции даты, либо сопоставление с образцом) для искомого столбца, поскольку это препятствует работе базы данных. в полной мере использовать индекс для этого столбца (и это включает в себя ненужные дополнительные вычисления для каждой строки). Вместо этого вы можете легко сгенерировать точное значение для поиска с помощью конкатенации переменной в запросе.

В более типичном случае, когда datum имеет реальные компоненты дня и времени, и вы хотите фильтровать по данный месяц вы должны сделать:

SELECT *
FROM table
WHERE datum >= concat(?, '-01') AND datum < concat(?, '-01') + interval 1 month

Обратите внимание, что это предполагает, что вы используете MySQL, потому что синтаксис предлагает это. Другие базы данных имеют эквивалентные способы построения дат из строк.

...