TSQL запрос и индекс вопрос - PullRequest
1 голос
/ 24 июля 2010

У меня есть таблица, в которой хранится информация о фотографии с идентификатором в качестве первичного ключа:

id (PK), название, album_id, posts_by, опубликовано, имя файла, теги, рейтинги, date_posted

Эта таблица будет содержать информацию о более 100 миллионов фотографий и Мне нужно часто запускать этот запрос:

1) получить все фотографии (только идентификатор, имя файла, заголовки столбцов) данного альбома

выберите идентификатор, имя файла, название из фотографий где album_id = @AlbumId и опубликовано = 1

2) получить все опубликованные фотографии данного пользователя, но исключить фотографии просматриваемого альбома

выберите идентификатор, имя файла, название из фотографий где posts_by = 'bob' и album_id <> 10 и опубликовано = 1

Я хочу избежать сканирования индекса и таблицы. Мне нужно максимально использовать поиск (скажем, 100%).

Можно ли это сделать? Какой тип индекса и какие столбцы помогут мне достичь этого?

Спасибо

Ответы [ 4 ]

2 голосов
/ 24 июля 2010

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

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

CREATE NONCLUSTERED INDEX IX01_Photos
  ON dbo.Photos(album_id, published, posted_by)
  INCLUDE(id, filename, title)

Рассуждение:

  • оба ваших наиболее частых запроса имеют предложения WHERE, использующие album_id и published - поэтому сначала используйте эти два столбца в своем индексе
  • Ваш второй запрос также включает posted_by в предложении WHERE - поместите его в тот же индекс, что и в третьем столбце
  • Во избежание дорогостоящего поиска закладок в реальной таблице данных, вы можете включить в индекс столбцы id, filename, title

Имея все эти вещи, вы должны видеть в основном поиск индекса по этому новому некластерному индексу для удовлетворения ваших запросов. Но опять же: в игру вступает множество других факторов, которые вы, вероятно, не упомянули в своем вопросе и, возможно, даже не думали о себе, - но этот подход должен дать вам хорошую отправную точку не меньше.

0 голосов
/ 24 июля 2010

Первичный ключ по Id.Сделайте это некластеризованным.Я предполагаю, что это не будет использоваться много (особенно если все поиски по альбомам или постерам).

Кластерный индекс по AlbumId.Похоже, он будет использоваться в большинстве запросов.

Некластеризованный индекс на Posted_By.С AlbumId кластеризованный индекс, он появится на уровне листа этого индекса, и, таким образом, действует как столбец INCLUDEd.В зависимости от использования может быть лучше иметь это в качестве кластерного индекса ... но как varchar (20), он будет занимать больше дискового пространства, а производительность будет ниже, чем у AlbumId (при условии, что AlbumId является целым).

Вы не можете опубликовать как столбец в индексе, так как вы не можете индексировать по битовым столбцам.И при этом вы не захотите - с двумя возможными значениями в 100M + строках SQL, вероятно, никогда не будет использовать его для оптимизации запросов.

Я бы порекомендовал нормализовать Posted_By (переместить его в свою собственную таблицу, дать свою собственную).суррогатный ключ и использовать его в качестве внешнего ключа в этой таблице).Это значительно уменьшит объем памяти в вашей основной таблице, увеличит общую производительность и позволит при необходимости перевернуть кластерный индекс в этот столбец.(Кроме того, если «Боб» отправляет сообщение в таблицу, а затем «Боб» со всего города также пишет, как вы можете отличить Боба от Боба?)

0 голосов
/ 24 июля 2010

Я бы предложил кластеризованный индекс на album_id и вторичный индекс на posted_by, если первый будет наиболее уязвимым. Инвертируйте их, если больше всего поражено posted_by. В зависимости от того, сколько фотографий есть для каждого album_id или posted_by, может быть вполне целесообразно фильтровать по published в коде вызова (другими словами, не добавляйте его как ограничение в запросе, скорее фильтр на стороне клиента). Если нет, то вам нужно добавить это опубликованное ограничение в запрос, но основное ограничение album_id должно означать, что выполняется только небольшое сканирование на published. Но, как уже говорилось, может быть проще просто выполнить фильтрацию на published стороне клиента.

0 голосов
/ 24 июля 2010

Вы не упомянули, нужно ли использовать date_posted или id в качестве критерия фильтра в запросе, поэтому может быть лучше использовать индекс CLUSTERED для нехронологического столбца (я предполагаю, что текущий КЛАСТЕРНЫЙ индекс - это ПК. Верно?).

Я бы создал индекс CLUSTERED для идентификатора альбома.

Если вы не можете изменить индекс CLUSTERED или есть много других запросов, которые используют существующий кластеризованный индекс, тогда я поддерживаю ответ @marc_s (и буду голосовать соответственно).

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