MariaDB SELECT с индексом используется, но выглядит как сканирование таблицы - PullRequest
1 голос
/ 27 марта 2020

У меня есть MariaDB 10.4 с зависшей таблицей (около 100 миллионов строк) для хранения просканированных сообщений. Таблица содержит 4x столбца, один из которых lastUpadate (datetime) и проиндексирован.

В последнее время я пытаюсь выбрать сообщения по lastUpdate. Большинство из них быстро возвращается с использованным индексом, но некоторые занимают минуты с меньшим количеством возвращенных записей и выглядят как сканирование таблицы.

Это объяснение запроса без условий.

> explain select 1 from SourceAttr;
+------+-------------+------------+-------+---------------+---------------+---------+------+----------+-------------+
| id   | select_type | table      | type  | possible_keys | key           | key_len | ref  | rows     | Extra       |
+------+-------------+------------+-------+---------------+---------------+---------+------+----------+-------------+
|    1 | SIMPLE      | SourceAttr | index | NULL          | idxCreateDate | 5       | NULL | 79830491 | Using index |
+------+-------------+------------+-------+---------------+---------------+---------+------+----------+-------------+

Это объяснение запроса и количество строк, возвращаемых для медленной. Число rows в объяснении почти совпадает с приведенным выше.

> select 1 from SourceAttr where (lastUpdate >= '2020-01-11 11:46:37' AND lastUpdate < '2020-01-12 11:46:37');
+------+-------------+------------+-------+---------------+---------------+---------+------+----------+--------------------------+
| id   | select_type | table      | type  | possible_keys | key           | key_len | ref  | rows     | Extra                    |
+------+-------------+------------+-------+---------------+---------------+---------+------+----------+--------------------------+
|    1 | SIMPLE      | SourceAttr | index | idxLastUpdate | idxLastUpdate | 5       | NULL | 79827437 | Using where; Using index |
+------+-------------+------------+-------+---------------+---------------+---------+------+----------+--------------------------+

> select 1 from SourceAttr where (lastUpdate >= '2020-01-11 11:46:37' AND lastUpdate < '2020-01-12 11:46:37');
394454 rows in set (14 min 40.908 sec)

Быстрое число.

> explain select 1 from SourceAttr where (lastUpdate >= '2020-01-15 11:46:37' AND lastUpdate < '2020-01-16 11:46:37');
+------+-------------+------------+-------+---------------+---------------+---------+------+---------+--------------------------+
| id   | select_type | table      | type  | possible_keys | key           | key_len | ref  | rows    | Extra                    |
+------+-------------+------------+-------+---------------+---------------+---------+------+---------+--------------------------+
|    1 | SIMPLE      | SourceAttr | range | idxLastUpdate | idxLastUpdate | 5       | NULL | 3699041 | Using where; Using index |
+------+-------------+------------+-------+---------------+---------------+---------+------+---------+--------------------------+

> select 1 from SourceAttr where (lastUpdate >= '2020-01-15 11:46:37' AND lastUpdate < '2020-01-16 11:46:37');
1352552 rows in set (2.982 sec)

Любая причина, которая может вызвать это?

Большое спасибо.

1 Ответ

2 голосов
/ 27 марта 2020

Когда вы видите type: index, это называется индексное сканирование . Это почти так же плохо, как сканирование таблицы.

Обратите внимание на rows: 79827437 в ОБЪЯСНЕНИИ двух медленных запросов. Это означает, что он проверяет более 79 миллионов элементов в отсканированном индексе, либо idxCreateDate, либо idxLastUpdate. Таким образом, он в основном проверяет каждую запись индекса, что занимает почти столько же времени, сколько и проверка каждой строки таблицы.

Принимая во внимание, что быстрый запрос говорит rows: 3699041, поэтому он оценивает менее 3,7 миллиона проверенных строк. Более чем в 20 раз меньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...