OrderBy на неуникальных столбцах будет работать при сканировании индекса? - PullRequest
0 голосов
/ 06 февраля 2020
id    market_id      date          keyword                 sku            a             b         c  
1        1        2019-01-01    some text for this      QAB-XU-VV        3.1           2.4       3.5
2        2        2019-01-02    some text for text      ABC-XA-VV        2.1           4.1       1.2
3        1        2019-01-03    some text for XXX       DDD-XA-RR        2.7           3.5       4.1

Мне нужно сделать запрос, подобный этому

   SELECT
      sku,
      keyword,
      SUM(a),
      SUM(b),
      SUM(c),
    FROM A
    WHERE market_id = 2 AND date BETWEEN '2020-01-01' and '2020-02-02'
    GROUP BY sku, keyword
    LIMIT 10
    OFFSET XX

Я использовал SampleTable (примите эту таблицу как SampleTable) и SampleTable(sku, keyword) составной-индекс. так что этот запрос будет делать index scan. время запроса быстрое, но мне нужно добавить LIMIT...OFFSET для разбивки на страницы. Так что мне нужно знать, что этот запрос будет сортироваться как SORT BY ID? Я не могу использовать ORDER BY ID, так как, если я использую это, этот запрос будет делать file sort и будет очень медленным, так как он будет использовать full scan вместо index scan. Вот что я путаю.

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

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

Предложение ORDER BY также имеет то же ограничение как запросы поиска: это должно сформировать самый левый префикс индекса. Во всех других случаях MySQL использует файловую сортировку.

Пожалуйста, помогите мне, в чем я не прав. Спасибо.

1 Ответ

0 голосов
/ 07 февраля 2020

WHERE, GROUP BY и ORDER BY хотят сканировать всю таблицу.

Один индекс может помочь.

В вашем запросе INDEX(market_id, date) (или индекс, начинающийся с этих двух столбцов) может избежать полного сканирования таблицы и сканирования только части индекса. Но это ничего не значит для GROUP BY или ORDER BY. Кроме того, поскольку предложение WHERE - это не все тесты =, захват столбцов GROUP BY бесполезен.

Если вам удалось пройти WHERE, тогда GROUP BY и ORDER BY приводят к отдельным проходам , если они не являются "идентичными".

Я считаю, что ваш запрос в его нынешнем виде обречен на 4 прохода:

  • Сканирование по индексу для обработки фильтрации по WHERE.
  • Сортировка и «группировка» результирующей временной таблицы
  • Сортировка по ORDER BY.
  • Пропуск OFFSET строки; только тогда вы можете доставить 10 желаемых по LIMIT.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...