Таблица имеет 100 000 записей, занимает 20-21 секунд при использовании агрегатной функции. Как оптимизировать этот запрос?
SELECT source, sum(product_price*quantity) AS price
FROM 'sheet'
WHERE source !=''
GROUP BY source
ORDER BY 'price' DESC
Я также использовал индексирование в таблице
ALTER TABLE 'dbname'.'sheet' ADD INDEX 'reprting_module' ('source'(30));
Это результат после объяснения запроса
Прежде всего, вы просите свой сервер MySQL выполнить некоторые вычисления в этом запросе, а затем отсортировать результаты. Это займет некоторое время. Он обязательно должен проверять каждую или почти каждую строку таблицы. Там нет волшебства, чтобы сделать эти операции мгновенными.
Во-вторых, ваш фильтр WHERE source != ''
Может победить вашу индексацию. Вместо этого вы можете попробовать использовать WHERE source > ''
. Это позволит планировщику запросов MySQL произвольно обращаться к вашему индексу, а затем сканировать его последовательно.
В- третьих, ваш подмножество source
индекса (source(30)
) не поможет производительности.
В-четвертых, вы можете попробовать создать составной индекс покрытия для этих столбцов:
ALTER TABLE dbname.sheet
ADD INDEX 'reprting_module' (source, product_price, quantity);
Затем напишите свой запрос следующим образом:
SELECT source, SUM(product_price*quantity) AS price
FROM sheet
WHERE source > ''
GROUP BY source
ORDER BY SUM(product_price*quantity) DESC
Если вам повезет, это будет немного быстрее. Зачем? Поскольку MySQL может удовлетворить весь ваш запрос путем случайного доступа индекса к первому непустому source
значению, затем последовательно сканировать только индекс для выполнения ваших вычислений.
Обратите внимание, что запрос, который я показал с индексом, который я показал, будет очень быстрым, если вы используете
WHERE source = 'some-particular-value'
сузить масштаб вычислений.
Индексы "Префикс", такие как INDEX(source(30))
, практически бесполезны. Пожалуйста, предоставьте SHOW CREATE TABLE
. Если source
может быть VARCHAR(255)
или меньше, просто добавьте INDEX(source)
Но это, вероятно, не полезно здесь, так как большая часть таблицы должна быть прочитана.
Сколько у вас RAM? Какова ценность innodb_buffer_pool_size
? Насколько велика (ГБ) таблица? Они объединяются, чтобы спросить, привязаны ли вы к процессору или привязаны к I/O, и может ли простое исправление настройки изменить его из ввода-вывода в CPU, тем самым, возможно, ускорить его до 2 секунд. (20 секунд кажется очень высоким для простых строк 100K).
MAX(LENGTH(source))
? TEXT
обрабатывается не так эффективно, как короткие VARCHARs
.