Занимает много времени при использовании агрегатной функции в запросе

0

Таблица имеет 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));  

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

Изображение 174551

  • 1
    Дайте нам определения таблиц, включая индексы
  • 1
    применить индексацию ..
Показать ещё 6 комментариев
Теги:
mysqli
query-performance

2 ответа

1

Прежде всего, вы просите свой сервер 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'

сузить масштаб вычислений.

  • 0
    Хорошо, спасибо за ваш ответ. Позвольте мне попробовать это ..
  • 0
    Третий пункт полезен. Спасибо человеку .. Моя проблема решена.
0

Индексы "Префикс", такие как INDEX(source(30)), практически бесполезны. Пожалуйста, предоставьте SHOW CREATE TABLE. Если source может быть VARCHAR(255) или меньше, просто добавьте INDEX(source) Но это, вероятно, не полезно здесь, так как большая часть таблицы должна быть прочитана.

Сколько у вас RAM? Какова ценность innodb_buffer_pool_size? Насколько велика (ГБ) таблица? Они объединяются, чтобы спросить, привязаны ли вы к процессору или привязаны к I/O, и может ли простое исправление настройки изменить его из ввода-вывода в CPU, тем самым, возможно, ускорить его до 2 секунд. (20 секунд кажется очень высоким для простых строк 100K).

  • 0
    В моем случае тип источника текста
  • 1
    @ Сумит - но нужно ли это? Что такое MAX(LENGTH(source)) ? TEXT обрабатывается не так эффективно, как короткие VARCHARs .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню