2010-05-27 2 views
6

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

Предположим, что есть таблица (Junk), и есть два запроса, которые выполняются в таблице, первый запрос выполняет поиск по имени, а второй запрос выполняет поиск по имени и ко всему. Как я работаю в базе данных, я обнаружил, что таблица была создана с двумя индексами, один для поддержки каждого запроса, например, так:

--drop table Junk1 
CREATE TABLE Junk1 
(
    Name char(5), 
    Something char(5), 
    WhoCares int 
) 

CREATE CLUSTERED INDEX IX_Name ON Junk1 
(
    Name 
) 

CREATE NONCLUSTERED INDEX IX_Name_Something ON Junk1 
(
    Name, Something 
) 

Теперь, когда я смотрел на двух индексов, кажется, что IX_Name является избыточное с IX_Name_Something может использоваться любым запросом, который хочет выполнить поиск по имени. Поэтому я хотел бы устранить IX_Name и сделать IX_Name_Something кластерный индекс вместо:

--drop table Junk2 
CREATE TABLE Junk2 
(
    Name char(5), 
    Something char(5), 
    WhoCares int 
) 

CREATE CLUSTERED INDEX IX_Name_Something ON Junk2 
(
    Name, Something 
) 

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

Я был бы признателен за любое понимание этого конкретного примера или указание мне больше информации об обслуживании кластеризованных индексов.

ответ

9

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

Вы можете облегчить эту проблему с помощью правильного кластерный индекс - один, что в идеале есть:

  • узкая (только одно поле, как можно)
  • статические (никогда не изменяется)
  • уникальный (так что SQL Server не нужно добавить 4 байта uniqueifiers в ваши ряды)
  • постоянно увеличивающийся (как INT IDENTITY)

Вам нужен узкий ключ (в идеале один INT), поскольку каждая запись в каждом некластеризованном индексе также будет содержать ключ кластеризации - вы не хотите класть много столбцов в свой ключ кластеризации, и вы не хотите ставить такие вещи, как VARCHAR (200)!

С постоянно увеличивающимся кластеризованным индексом вы никогда не увидите случай разделения страницы. Единственная фрагментация, с которой вы могли столкнуться, - это удаление (проблема «швейцарского сыра»).

ЗАКАНЧИВАТЬ Excellet сообщений Kimberly Tripp в блоге на индексации - в первую очередь:

Предположим, что имеется таблица (Junk) и есть два запроса, которые сделаны на таблицы, первый запрос выполняет поиск по Имя и второй запрос выполняет поиск по Имя и Что нибудь. Как я работаю на базе данных я обнаружил, что таблица была создана с двумя индексами, один для поддержки каждого запроса, так:

Это, безусловно, не нужно - если у вас есть один индекс на (Name, Something), этот индекс также может и так же использоваться, если вы ищете и ограничиваете только WHERE Name = abc - наличие отдельного индекса с только столбцом Name совершенно не нужно и только тратит пространство (и стоит время, которое нужно обновлять).

Таким образом, вам нужен только один индекс на (Name, Something), и я согласен с вами - если у вас нет других индексов на этой таблице, вы должны иметь возможность сделать это кластеризованным ключом. Поскольку этот ключ не будет постоянно увеличиваться и может измениться тоже (правильно?), Это может быть не такая прекрасная идея.

Другим вариантом было бы ввести суррогатной ID INT IDENTITY и кластер на том, что - с двумя преимуществами:

  • это все хорошо кластерный ключ должен быть, в том числе постоянно растет -> вы никогда не будете иметь любой проблемы с разбиениями страниц и производительностью для операций INSERT
  • вы все еще получаете все преимущества наличия ключа кластеризации (см сообщений в блоге Кима Tripps' - кластерные таблицы почти всегда предпочтительнее кучи)
+1

Ницца, подробное объяснение. –

0

Кто-то предположил, что первая схема индексации должна быть, так как это приведет к более эффективной вставки/удаления

Это фиктивный иск. Упорядоченные данные - это упорядоченные данные и выполняется то же самое IO.

SET STATISTICS IO ON 
-- your insert statement here 
0

Вы можете создать кластерный индекс только на одной колонке, а не два или более, выберите столбец, который ваше приложение будет в основном на-опрос, как подстановочные запросов на fullnames клиента и т.д. (см discussion)

+0

Это неверно, пожалуйста, прочитайте: http://msdn.microsoft.com/en-us/library/aa933131(SQL.80).aspx «таблица может содержать только один кластерный индекс. Однако индекс может содержать несколько столбцов " – Anssssss

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

  • Нет связанных вопросов^_^