Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Почему при использовании переменной запрос выполняется дольше? / 5 сообщений из 5, страница 1 из 1
27.03.2018, 02:03
    #39620843
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему при использовании переменной запрос выполняется дольше?
Доброго дня.
Таблица содержит около 11 миллионов записей, поле для отбора
Код: sql
1.
`harvest_date` date NOT NULL

на нем построен индекс
Код: sql
1.
KEY `harvest_date` (`harvest_date`)



Три варианта задания условия WHERE. Явное задание сравниваемой даты и вычисление с помощью функции дают примерно одинаковый результат по времени выполнения. А вот при использовании переменной для сравниваемого значения время выполнения получается примерно вдвое дольше.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
mysql> SET @d = DATE(DATE_SUB(NOW() , INTERVAL 1 YEAR));
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @d;
+------------+
| @d         |
+------------+
| 2017-03-27 |
+------------+
1 row in set (0.00 sec)

mysql> SELECT SQL_NO_CACHE COUNT(1) FROM `un_harvest_log` WHERE `harvest_date` > '2017-03-27';
+----------+
| COUNT(1) |
+----------+
|  1916496 |
+----------+
1 row in set, 1 warning (0.63 sec)

mysql> SELECT SQL_NO_CACHE COUNT(1) FROM `un_harvest_log` WHERE `harvest_date` > DATE(DATE_SUB(NOW() , INTERVAL 1 YEAR));
+----------+
| COUNT(1) |
+----------+
|  1916496 |
+----------+
1 row in set, 1 warning (0.60 sec)

mysql> SELECT SQL_NO_CACHE COUNT(1) FROM `un_harvest_log` WHERE `harvest_date` > @d;
+----------+
| COUNT(1) |
+----------+
|  1916496 |
+----------+
1 row in set, 1 warning (1.12 sec)

mysql>



План запроса разный получается.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
mysql> EXPLAIN SELECT SQL_NO_CACHE COUNT(1) FROM `un_harvest_log` WHERE `harvest_date` > '2017-03-27';
+----+-------------+----------------+------------+-------+---------------+--------------+---------+------+---------+----------+--------------------------+
| id | select_type | table          | partitions | type  | possible_keys | key          | key_len | ref  | rows    | filtered | Extra                    |
+----+-------------+----------------+------------+-------+---------------+--------------+---------+------+---------+----------+--------------------------+
|  1 | SIMPLE      | un_harvest_log | NULL       | range | harvest_date  | harvest_date | 3       | NULL | 1984739 |   100.00 | Using where; Using index |
+----+-------------+----------------+------------+-------+---------------+--------------+---------+------+---------+----------+--------------------------+
1 row in set, 2 warnings (0.00 sec)

mysql> EXPLAIN SELECT SQL_NO_CACHE COUNT(1) FROM `un_harvest_log` WHERE `harvest_date` > DATE(DATE_SUB(NOW() , INTERVAL 1 YEAR));
+----+-------------+----------------+------------+-------+---------------+--------------+---------+------+---------+----------+--------------------------+
| id | select_type | table          | partitions | type  | possible_keys | key          | key_len | ref  | rows    | filtered | Extra                    |
+----+-------------+----------------+------------+-------+---------------+--------------+---------+------+---------+----------+--------------------------+
|  1 | SIMPLE      | un_harvest_log | NULL       | range | harvest_date  | harvest_date | 3       | NULL | 1984739 |   100.00 | Using where; Using index |
+----+-------------+----------------+------------+-------+---------------+--------------+---------+------+---------+----------+--------------------------+
1 row in set, 2 warnings (0.00 sec)

mysql> EXPLAIN SELECT SQL_NO_CACHE COUNT(1) FROM `un_harvest_log` WHERE `harvest_date` > @d;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | no matching row in const table |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
1 row in set, 2 warnings (0.00 sec)

mysql> 

В варианте с переменной ключ в плане не используется и попытка USE KEY никакого влияния на план и на запрос не оказывает.
Почему так происходит и можно ли как-то выправить?
...
Рейтинг: 0 / 0
27.03.2018, 07:33
    #39620869
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему при использовании переменной запрос выполняется дольше?
Если запрос приводит к warning - его ОБЯЗАТЕЛЬНО надо показывать... порой там прекрасно видно, откуда грабли.
...
Рейтинг: 0 / 0
27.03.2018, 12:08
    #39621064
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему при использовании переменной запрос выполняется дольше?
vkle,

переменная может изменяться во время выполнения запроса, потому не может использоваться для indexscan.
...
Рейтинг: 0 / 0
27.03.2018, 12:46
    #39621109
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему при использовании переменной запрос выполняется дольше?
AkinaЕсли запрос приводит к warning - его ОБЯЗАТЕЛЬНО надо показывать... порой там прекрасно видно, откуда грабли.SQL_NO_CACHE использовать не рекомендуют, в будущем бкдет депрекейтед - вот такой варнинг. Мда, что вместо него будет...
...
Рейтинг: 0 / 0
27.03.2018, 12:51
    #39621114
vkle
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Почему при использовании переменной запрос выполняется дольше?
Melkij,

Так и что, использование переменной в условии отбора гарантировано отменяет использование индекса, без вариантов?
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Почему при использовании переменной запрос выполняется дольше? / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]