MySQL медленная группа по / упорядочить по - PullRequest
6 голосов
/ 26 декабря 2011

Следующий запрос является относительно медленным (0,7 секунды с ~ 6 тыс. Строк)

SELECT items.*, COUNT(transactions.ID)
   FROM items
  INNER JOIN users ON (items.USER = users.ID)
   LEFT JOIN transactions ON (items.id = transactions.item)
  WHERE items.ACTIVE = 1
    AND items.DELETED_AT IS NULL
  GROUP BY items.ID
  ORDER BY items.DATE DESC
  LIMIT 20

Но значительно ускоряется при заказе items.ID DESC вместо items.DATEОбъединение транзакций происходит с большой таблицей (~ 250 тыс. Строк) и является однозначным.Столбец даты имеет индекс.

Можно ли как-то улучшить производительность ORDER BY?

РЕДАКТИРОВАТЬ: индексы для items.user, Transactions.item и items.date.У элементов 49 столбцов, у 76 пользователей и транзакций 17.

Ответы [ 3 ]

5 голосов
/ 26 декабря 2011

Индексы могут влиять на производительность предложений ORDER BY.Эта страница справочника MySQL , вероятно, стоит вашего времени.По сути, если вы упорядочиваете по столбцу, который является частью индекса, который MySQL использует для запроса, MySQL может использовать индекс для сортировки, а не сами данные.

В вашем конкретном запросе тот факт, чтоИндекс столбца DATE не имеет значения, так как этот индекс, вероятно, не используется в вашем запросе.Ваш оператор WHERE содержит items.ACTIVE и items.DELETED_AT, и если эти столбцы имеют индекс, который используется для WHERE, который не включает столбец DATE, MySQL не может использовать этот индекс для сортировкина DATE и, скорее всего, прибегает к сортировке файлов.

Если вы сможете найти индекс, который может использоваться как WHERE, так и ORDER BY, вы получите оптимизациюувеличение.В этом случае items.ACTIVE выглядит как столбец с низкой кардинальностью, поэтому, предполагая, что items.DELETED_AT является датой, я бы, вероятно, попробовал индекс для этой таблицы, например INDEX(DELETED_AT,DATE).

Используйте EXPLAIN SELECT... чтобы узнать больше о том, что там происходит, вы можете получить дополнительную информацию.

2 голосов
/ 14 октября 2014

SELECT * FROM (SELECT * FROM wp_users WHERE 1 GROUP BY ID, предел 0,10) как X ORDER BY ID DESC

Приведенный выше запрос работает отлично, я использовал его в очень длинной базе данных.Он ЗАКАЗЫВАЕТСЯ путем перечисления 10 ИЛИ (хх) элементов, которые мы получаем из внутреннего запроса на выборку, так что это очень БЫСТРО !!

0 голосов
/ 02 января 2012

Это то, что МОЖЕТ (читай не гарантировано) помочь.

  1. Исключить элементы * на элементах. * И перечислить каждое поле по отдельности.49 столбцов - это много, вам действительно нужно их все?
  2. Обычно движок оптимизирует запросы так, чтобы при объединении учитывался ограничивающий критерий.Возможно, план, используемый движком, не делает этого (нужно знать результаты плана, чтобы знать), поэтому перестановка предложения where и присоединение МОЖЕТ (маловероятно) помочь, заставив движок рассмотреть это.(См. Ниже)
  3. Перестроить статистику таблицы, если с течением времени произошло много обновлений, вставок, удалений, возможно, статистика таблицы отключена и ее необходимо перестроить для каждой таблицы

.

SELECT items.[list fields], COUNT(transactions.ID)
   FROM items
  INNER JOIN users ON (items.USER = users.ID)
        AND items.Active=1 
        AND items.DELETED_AT is Null
   LEFT JOIN transactions ON (items.id = transactions.item)
  GROUP BY items.ID
  ORDER BY items.DATE DESC
  LIMIT 20
...