Таблица индексации с дубликатами MySQL / SQL Server с миллионами записей - PullRequest
0 голосов
/ 05 февраля 2010

Мне нужна помощь в индексации в MySQL. У меня есть таблица в MySQL со следующими строками:

ID Store_ID Feature_ID Order_ID Viewed_Date Deal_ID IsTrial
Идентификатор генерируется автоматически. Store_ID - от 1 до 8. Feature_ID - от 1, скажем, 100. Дата просмотра - это дата и время, когда данные вставляются. IsTrial: 0 или 1.
Вы можете игнорировать Order_ID и Deal_ID из этого обсуждения.

В таблице содержатся миллионы данных, и у нас есть серверная часть отчетности, которая должна просматривать количество просмотров за определенный период или в целом, где пробная версия равна 0 для определенного идентификатора магазина и для определенной функции.

Запрос принимает форму:

select count(viewed_date) 
from theTable
where viewed_date between '2009-12-01' and '2010-12-31'
and store_id = '2' 
and feature_id = '12'
and Istrial = 0

В SQL Server вы можете использовать отфильтрованный индекс для использования в Istrial. Есть ли что-нибудь подобное в MySQL? Кроме того, Store_ID и Feature_ID содержат много повторяющихся данных. Я создал индекс, используя Store_ID и Feature_ID. Хотя это, похоже, сократило период поиска, мне нужно лучшее улучшение, чем это. Прямо сейчас у меня более 4 миллионов строк. Для поиска конкретного запроса, подобного приведенному выше, он просматривает 3,5 миллиона строк, чтобы подсчитать 500 000 строк.

PS. Я забыл добавить фильтр view_date в запросе. Теперь я сделал это.

Ответы [ 5 ]

0 голосов
/ 09 июня 2010

Лучший способ, который я нашел в решении этой проблемы, - это пропустить рекомендацию DTA и сделать это самостоятельно следующим образом:

  • Используйте Profiler, чтобы найти самые дорогие запросы с точки зрения использования ЦП (возможно, блокирующие запросы) и применить индексы к таблицам на основе этих запросов. Если план выполнения запроса можно изменить, чтобы уменьшить время чтения, записи и общее время выполнения, то сначала сделайте это. Если нет, то в этом случае запрос является тем, чем он является, тогда примените комбинацию кластеризованного / некластеризованного индекса для наилучшего соответствия. Это зависит от природы существующих табличных индексов, общего количества байтов столбцов, участвующих в индексе, и т. Д.
  • Запускайте запросы в SSMS, чтобы найти наиболее часто выполняемые запросы, и делайте то же, что и выше.
  • Создайте расписание дефрагментации для реорганизации или перестройки индексов в зависимости от степени их фрагментации.

Я уверен, что другие могут предложить хорошие идеи. Это дало мне хорошие результаты. Я надеюсь, что кто-то может использовать эту помощь. Я думаю, что DTA не делает вещи быстрее с точки зрения индексации, потому что вам действительно нужно пройти через все индексы, которые он собирается создать. Это более верно для базы данных, которая сильно пострадала.

0 голосов
/ 05 февраля 2010

Возможно, вы захотите подумать о разделении этой таблицы по горизонтали. Вы можете запустить ночную работу, которая помещает каждый store_id в отдельную таблицу. Или посмотрите на feature_id, да, это много таблиц, но если вам не нужны данные в реальном времени. Я бы выбрал этот маршрут.

0 голосов
/ 05 февраля 2010

Ну, вы можете расширить свой индекс, чтобы он состоял из Store_ID, Feature_ID и IsTrial. Вы не станете лучше, чем это, с точки зрения производительности.

0 голосов
/ 05 февраля 2010

Моей первой идеей будет индекс для (feature_id, store_id, istrial), так как feature_id - это столбец с самой высокой энтропией Шеннона. Но, не зная статистики по feature_id, я не уверен. Может быть, вам лучше создать два индекса (store_id, feature_id, istrial) как другой и позволить оптимизатору разобраться в этом. Преимущество использования всех трех столбцов заключается в том, что база данных может отвечать на ваш запрос только из индекса, что также должно повысить производительность.

Но если ни один из ваших столбцов не является достаточно избирательным для достаточного повышения производительности индекса, вам, возможно, придется прибегнуть к денормализации, используя триггеры INSERT / UPDATE для заполнения второй таблицы (feature_id, store_id, istrial, view_count). Это, конечно, замедлит вставки и обновления ...

0 голосов
/ 05 февраля 2010

Если вам нужно оптимизировать этот запрос специально в MySQL, почему бы не добавить istrial в конец существующего индекса для Store_ID и Feature_ID. Это полностью отфильтровывает предложение WHERE и сможет извлечь COUNT из сводной информации о количестве элементов в индексе, если таблица - MyISAM. Все ваши существующие запросы, использующие текущий индекс, также останутся неизменными.

edit: также, я не уверен, почему вы делаете COUNT(viewed_date) вместо COUNT(*)? viewed_date когда-либо NULL? Если нет, вы можете просто использовать COUNT(*), что избавит вас от необходимости переходить к файлу .MYD, если вы примете его в сочетании с моим другим предложением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...