Почему MySQL (MariaDB) занял более 3 минут для подсчета записей по следующему запросу? - PullRequest
0 голосов
/ 28 октября 2018

Я ищу причину и предложения.В моей таблице около 1,4 миллиона строк, и когда я выполняю следующий запрос, это заняло более 3 минут.Я добавил счетчик только для показа результата.Мой реальный запрос без подсчета.

MariaDB [ams]> SELECT count(asin) FROM asins where asins.is_active = 1 
and asins.title is null and asins.updated < '2018-10-28' order by sortorder,id;

+-------------+
| count(asin) |
+-------------+
|      187930 |
+-------------+


1 row in set (3 min 34.34 sec)

Структура

id int(9) Primary
asin varchar(25) UNIQUE
is_active int(1) Index 
sortorder int(9) Index 

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.Заранее благодаримnull and asins.updated <'2018-10-28' - порядок сортировки, id; </p>

enter image description here

Ответы [ 4 ]

0 голосов
/ 18 декабря 2018

Когда вы создаете составной индекс, и его часть основывается на диапазоне, вам сначала нужна часть на основе диапазона.

Итак, попробуйте индекс (обновленный, is_active, title)

ЭтоОбновленный путь становится префиксом и может использоваться в запросах диапазона.

0 голосов
/ 28 октября 2018

Похоже, у вас есть индекс на is_active и обновленный.Таким образом, этот индекс будет сканироваться (как сканирование таблицы, каждая запись в индексе считывается), но поскольку заголовок отсутствует в индексе, будет вторая операция, которая ищет заголовок в таблице.Вы можете думать об этом как о соединении между индексом и таблицей.Если большинство записей в индексе соответствуют вашим условиям, то объединение будет включать большую часть данных в таблице.Большие объединения выполняются медленно.

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

См. https://dba.stackexchange.com/questions/110707/how-can-i-force-mysql-to-ignore-all-indexes для способа принудительного полного сканирования таблицы.Попробуйте и посмотрите, быстрее ли ваш запрос.

0 голосов
/ 29 октября 2018

Попробуйте:

INDEX(is_active, updated),
INDEX(is_active, sortorder, id)

И, пожалуйста, укажите SHOW CREATE TABLE.

. С первым из этих индексов будет выполнена некоторая фильтрация, но затем все равно придетсясортировка результатов.

Со вторым индексом оптимизатор может решил отфильтровать только по столбцу =, а затем избежать сортировки, запустив в ORDER BY.Риск состоит в том, что ему все равно придется набрать столько строк, что избегать сортировки не стоит.

Какой процент таблицы имеет is_active = 1?Какой процент имеет ноль title?Какой процент в этом диапазоне дат?

0 голосов
/ 28 октября 2018

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

Для этого запроса ORDER BY не требуется (но это не должно влиять на производительность:

SELECT count(asin)
FROM asins 
WHERE asins.is_active = 1 AND
      asins.title is null AND
      asins.updated < '2018-10-28' ;

Тогда вам нужен индекс для(is_active, title, updated).

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