MySQL заказ по оптимизации - PullRequest
4 голосов
/ 15 января 2012

Ниже приведена структура таблицы: -

Статья: ID, название, описание, дата публикации, количество просмотров, количество публикаций

Первичный ключ: ID

Используемый запрос:

Select Title FROM Article ORDER By ViewsCount DESC, PublishedDateTime ASC

Как видите, я смешиваю ASC и DESC и в соответствии с MySQL Order By Optimization, индексы не будут использоваться.

Я подумал использовать составной индекс, используя ViewsCount и ОпубликованоDateTime. Вы рекомендуете использовать 2 разных ключа вместо составного индекса. Но потом я прочитал, что составной индекс лучше, чем использование двух разных ключей (если будут использоваться оба поля).

Поделились информацией:

Таблица содержит более 550 тыс. Записей, а также у меня большие проблемы с добавлением и удалением индексов для целей тестирования. Что вы, ребята, рекомендуете? Стоит ли тестировать на небольшом образце?

Ниже приведено еще несколько идей:

Используемые индексы:
1) Количество просмотров
2) Дата публикацииВремя.
3) ViewsCount & ОпубликованоDateTime (названное ViewsDate_Index)

A) ОБЪЯСНЕНИЕ Смешивание запросов ASC и DESC:

EXPLAIN SELECT title FROM  `article` ORDER BY ViewsCount DESC , PublishedDateTime ASC  LIMIT 0 , 20    

====+===============+=========+======+===============+=====+=========+======+========+================+
id  | select_type   | table   | type | possible_keys | key | key_len | ref  | rows   | Extra
1   | SIMPLE        | article | ALL  | NULL          | NULL| NULL    | NULL | 550116 |  Using filesort
====+===============+=========+======+===============+=====+=========+======+========+================+

B) ОБЪЯСНЕНИЕ Запрос с использованием того же порядка сортировки:

EXPLAIN SELECT title FROM  `article` ORDER BY ViewsCount DESC , PublishedDateTime DESC  LIMIT 0 , 20

====+===============+=========+=======+===============+=================+=========+=============+========+================+
id  | select_type   | table   | type  | possible_keys | key             | key_len | ref         | rows   | Extra
1   | SIMPLE        | article | index | NULL          | ViewsDate_Index | 16      | NULL        | 550116 |  
====+===============+=========+=======+===============+=================+=========+=============+========+================+

Вы можете видеть, что если ViewsCount и ОпубликованоDateTime имеют 2 одинаковый порядок сортировки, тогда он использует индекс ViewsDate_Index. Одна вещь, которая показалась мне странной, это то, что возможные_ключи имеют значение ПУСТО (NULL), и все же он выбирает индекс. Может кто-нибудь объяснить причину этого.

Также есть советы по добавлению индексов в эту таблицу, поскольку для добавления нового индекса требуется много времени. Будем благодарны за любые обходные пути или помощь в этом отношении.

Ответы [ 2 ]

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

На практике индексы не будут использоваться даже для ORDER By ViewsCount, PublishedDateTime здесь, так как вы ВЫБИРАЕТЕ все столбцы и не применяете никаких условий. Это настоящий запрос? Потому что любые условия испортят ваши оптимизации.

Если ваша таблица настолько мала, что вы собираетесь ее извлекать целиком, индексы только замедляют ваш запрос. (Относится к исходному запросу: SELECT * FROM article ORDER BY ViewsCount DESC, PublishedDateTime;)

UPD

В случае, если у вас есть 500K + строк, я думаю, вы собираетесь использовать предложение LIMIT. Я бы сделал следующее:

  1. добавить индекс для (ViewCount, ОпубликованоDateTime)

  2. переписать запрос следующим образом:

    SELECT Title
    FROM (
        SELECT id
        FROM article
        ORDER BY ViewsCount DESC, PublishedDateTime
        LIMIT 100, 100
    ) ids
    JOIN article
    USING (id);
    

Заказу будет выгодно работать с подмножеством данных из индекса покрытия. Объединение только получит Названия по идентификаторам.

UPD2

Еще один запрос, который может работать намного лучше, когда количество элементов ViewCount довольно мало (хотя вам следует выполнить тестирование):

SELECT Title
FROM (
  SELECT ViewCount
  FROM article
  GROUP BY ViewCount DESC) as groups
JOIN article USING (ViewCount)
LIMIT 0, 100;

Предполагается, что у вас есть индекс (ViewCount, ОпубликованоDateTime) для таблицы.

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

Прежде всего, запустите весь запрос вживую и посмотрите, как он выполняется.Когда у вас закончатся тесты, вставьте запрос в консоль MySQL и добавьте к нему EXPLAIN.MySQL не будет выполнять запрос, но будет отображать свой план выполнения запроса, в том числе информацию о том, где, по его мнению, важно оптимизировать, какие индексы он будет использовать, сколько строк он должен пройти и насколько эффективно он будет проходить каждый наборряды, между прочим также.Лучший способ измерить проблему производительности - это сравнительный анализ.Используйте это часто.

...