Как улучшить производительность подсчета без индексации большего количества полей? - PullRequest
1 голос
/ 20 февраля 2012

В таблице более 2 миллионов записей.

Я хочу подсчитать, сколько ошибок (с проверкой) в таблице и сколько было проверено.

Я делаю два запроса:

SELECT count(*) as CountError FROM table WHERE checked = 1 AND error != ''

-

SELECT count(*) as Checked FROM table WHERE checked = 1

Производительность очень низкая, для получения результата требуется около 5 минут.Как это улучшить?

У меня уже есть индекс в поле status для производительности ОБНОВЛЕНИЕ.

Если я внесу в индекс в поле checked - тогда произойдет выполнение ОБНОВЛЕНИЯ, чего я не хочу.

ОБНОВЛЕНИЕ произойдет больше, чем ВЫБОР.

Таблица - Innob

Ответы [ 2 ]

3 голосов
/ 20 февраля 2012

Вы можете попробовать, если оба подсчета в одном запросе выполняются быстрее:

select
  count(*) as CountError,
  sum(case when error != '' then 1 else 0 end) as Checked
from table
where checked = 1

Однако о разнице, вероятно, говорить не о чем. Если вы действительно хотите разницу, вам нужно добавить индекс. Подумайте, что на самом деле будет означать воздействие, и проведите реальный тест, чтобы понять, каким может быть это воздействие на самом деле. Если обновление становится на 10% медленнее, а выборка - на 100000% быстрее, это все равно может стоить.

0 голосов
/ 20 февраля 2012

Ваша проблема здесь в том, что ваше проверенное поле имеет значение 1 или 0, что означает, что MySQL необходимо выполнить сканирование таблицы, даже если у вас есть ключ, так как он не может эффективно определить, где находится разделение между 0 и 1, особенно на большое количество строк.

Основной совет, который я бы предложил, - это тот, который вам не нужен, который должен индексироваться, поскольку тогда SELECT SUM(checked) AS Checked FROM table WHERE checked=1 сможет использовать индекс без попадания в таблицу.

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

Без дополнительной информации относительно точного назначения этой таблицы, причины, по которой вы не разрешаете индексировать этот столбец и т. Д., Трудно предложить что-то более полезное, чем вышеуказанное + метательное оборудование.

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