2015-09-29 10 views
2

У меня проблема с заказом двух столбцов.Mysql: заказ на две колонки, используйте filesort

EXPLAIN SELECT * FROM articles WHERE option <>0 AND deleted=0 ORDER BY 
    date_added DESC, category_id DESC LIMIT 25 OFFSET 500 

possible_keys типа ID SELECT_TYPE таблицы ключевых key_len реф строка Дополнительных 1 ПРОСТЫХ статьи ALL NULL NULL NULL NULL 437168 Использования где; Использование FileSort

добавить одиночные индексы для (опция, удаляемого, DATE_ADDED, CATEGORY_ID)

Когда я использовал:

EXPLAIN SELECT * FROM articles WHERE option <>0 AND deleted=0 ORDER BY 
    date_added DESC LIMIT 25 OFFSET 500 

или

EXPLAIN SELECT * FROM articles WHERE option <>0 AND deleted=0 ORDER BY 
    category_id DESC LIMIT 25 OFFSET 500 

Использование только где

Я попробовал добавить индекс (опция, deleted, date_added, category_id), но он работает только при попытке сортировки по одному столбцу.

ответ

1

Это будет очень трудно получить MySQL, чтобы использовать индекс для данного запроса:

SELECT * 
FROM articles 
WHERE option <> 0 AND deleted = 0 
ORDER BY date_added DESC 
LIMIT 25 OFFSET 500 

Вы можете попробовать композитный индекс: articles(deleted, date_added, option). Покрывая WHERE и ORDER BY, MySQL может использовать.

Если вы можете добавить optionflag колонку для равенства тестирования (а не <>), то напишите запрос как:

SELECT * 
FROM articles 
WHERE optionflag = 1 AND deleted = 0 
ORDER BY date_added DESC 
LIMIT 25 OFFSET 500; 

Тогда индекс articles(deleted, optionflag, date_added desc) будет хорошо работать.

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

SELECT a.* 
FROM (SELECT * 
     FROM articles 
     WHERE deleted = 0 
     ORDER BY date_added DESC 
    ) a 
WHERE option <> 0 
LIMIT 25 OFFSET 500; 

Это материализуется промежуточный результат, но он делает в order by все равно. И окончательный заказ не гарантированно всплывает во внешнем запросе, но он действительно работает на практике (и почти гарантирован из-за материализации).

Смежные вопросы