Что следует индексировать для улучшения производительности? - PullRequest
1 голос
/ 29 мая 2011

Учитывая этот запрос, какой столбец или столбцы следует индексировать для оптимизации производительности запроса?

SELECT *
  FROM `activities`
 WHERE (user_id = 90000 AND activity_type_id IN(300,400,808,9494))
 ORDER BY created_at DESC
 LIMIT 70

Ответы [ 8 ]

2 голосов
/ 29 мая 2011

Как правило, фильтры выбора могут использовать индексы на user_id или activity_type_id или на обоих (в любом порядке).

Операция заказа может использовать фильтр на created_at.

Вполне вероятно, что для этого запроса составной индекс на (user_id, activity_type_id) даст лучший результат, предполагая, что MySQL действительно может его использовать.В противном случае, вероятно, будет лучше индексировать user_id, чем activity_type_id, потому что это может обеспечить лучшую селективность.Одна из причин для того, чтобы думать, что было бы 4 подсекции индекса для сканирования, если он использует индекс на activity_type_id, по сравнению с только одним подразделом для сканирования, если он использует индекс только на user_id.

Попытка полагаться на индекс для порядка сортировки, вероятно, будет означать полное сканирование таблицы, поэтому это менее вероятно, будет полезным.Я бы не стал создавать индекс для created_at для поддержки этого запроса;могут быть другие запросы, где это будет полезно.

2 голосов
/ 29 мая 2011

Конечно, все столбцы в предложениях WHERE должны быть проиндексированы.

Но предложение IN, вероятно, потребует сканирования таблицы.

Я думаю, что чтение этих ответов может помочь:

MySQL не использует индексы с предложением WHERE IN?

0 голосов
/ 30 мая 2011

Чтобы принять правильное решение, вы должны принять во внимание следующее:

Если user_id является частью первичного ключа (вы сказали, что это, вероятно, так), то является ли первичный ключ кластеризованным индексом для таблицы? Если это так, находится ли user_id в первой позиции в кластерном индексе? Если да, то сколько действий вы ожидаете иметь на пользователя? Если на пользователя приходится 1-40 действий, то добавление еще одного индекса не будет полезным и снизит производительность вставки. Причина в том, что все строки действий для пользователя будут сгруппированы вместе и, вероятно, будут на одной странице базы данных, поэтому добавление activity_type_id к индексу не поможет.

Если первичный ключ не кластеризован и user_id не находится на первой позиции в первичном ключе, или user_id не находится в первичном ключе, тогда вам лучше всего ставить некластеризованный индекс с user_id, activity_type_id , Оптимизатор запросов должен быть достаточно умным, чтобы использовать индекс, поскольку и user_id, и activity_type_id находятся в операторе where даже при наличии предложения IN. Вы также можете добавить create_at в конец индекса, так как вы упорядочиваете результаты запроса таким образом.

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

0 голосов
/ 29 мая 2011

я бы вообще не создавал никаких дополнительных индексов, вместо этого я бы спроектировал свою таблицу так, чтобы она в полной мере использовала кластерный первичный ключ innodb!

create table activities
(
user_id int unsigned not null,
activity_id smallint unsigned not null,
primary key (user_id, activity_id) -- composite clustered primary key order is important
)
engine=innodb;

или

create table activities
(
user_id int unsigned not null,
activity_id smallint unsigned not null,
primary key (activity_id, user_id) -- hmmmm the other way round, why is that ?
)
engine=innodb;

Кроме того, прочитайте следующее:

MySQL и NoSQL: помогите выбрать правильный

Как избежать "использования временного" во многих- ко многим запросам?

60 миллионов записей, выберите записи за определенный месяц.Как оптимизировать базу данных?

Перезапись mysql select для сокращения времени и записи tmp на диск

Надеюсь, это поможет и помните innodb FTW;)

0 голосов
/ 29 мая 2011

Я бы добавил два индекса в таблицу действий, один из которых (user_id, activity_type_id), а другой - (созданный_дт).Я бы также очень внимательно посмотрел на то, какие поля из таблицы «действия» фактически используются;если вы можете уменьшить количество извлеченных полей, вы можете улучшить время отклика.Я бы также взял план запроса до внесения каких-либо изменений в базу данных, а затем сравнил бы его с планом, сгенерированным после внесения любых / всех изменений.

Поделиться инаслаждаться.

0 голосов
/ 29 мая 2011

Предполагая, что вы не скрываете JOIN в реальном производственном коде, индексирование "activity_type_id" должно быть лучшим.

0 голосов
/ 29 мая 2011

Я бы индексировал только user_id ..

0 голосов
/ 29 мая 2011

Вы выполняете поиск по user_id и activity_type_id, поэтому создайте индексы для обоих столбцов.

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