Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) правильное создание индексов (число прочтений - 2903 )
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
правильное создание индексов
25. Августа 2010 :: 08:35
Печать  
Имею MS SQL Server 2008. Есть табличка Events.
Создал для неё индекс по полям BaseID (тип int), ObjectFullID (тип varchar(23)). Вот скрипт создания:
Код
Выбрать все
CREATE NONCLUSTERED INDEX [idx_ObjectFullID] ON [dbo].[Events]
(
	[BaseID] ASC,
	[ObjectFullID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
 


Теперь выполняю запрос:
Код
Выбрать все
SELECT
	[UserID]
  FROM [dbo].[Events]
  where BaseID = 2 AND [ObjectFullID] = 'B1  DZ   DJZ	     ' 


В плане выполнения вижу ФуллСкан таблицы, а ожидал просмотр по индексу.
Что я сделал не так?
  
Наверх
 
IP записан
 
leshik
1c++ donor
Отсутствует



Сообщений: 820
Местоположение: Пятигорск
Зарегистрирован: 22. Апреля 2007
Пол: Мужской
Re: правильное создание индексов
Ответ #1 - 25. Августа 2010 :: 08:46
Печать  
Не обновил статистику по таблице
DBCC UPDATE STATISTICS [dbo].[Events]
  
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #2 - 25. Августа 2010 :: 08:47
Печать  
В Menegment Studio оказывается всё очень красиво и доступно. Он мне подсказал, что надо бы создать такой индекс:
Код
Выбрать все
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Events] ([ObjectFullID],[BaseID])
INCLUDE ([UserID])
GO
 


Т.е. надо бы включить колонку "UserID" (без этого включения в индекс не попадаем). Так всегда было в MS SQL?
И еще вопрос: как правильно выбирать порядок столбцов, входящих в индекс?
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #3 - 25. Августа 2010 :: 08:52
Печать  
leshik писал(а) 25. Августа 2010 :: 08:46:
Не обновил статистику по таблице
DBCC UPDATE STATISTICS [dbo].[Events]

Не помогает. перестроение/реорганизацию тоже пробовал.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #4 - 25. Августа 2010 :: 09:04
Печать  
JohnyDeath писал(а) 25. Августа 2010 :: 08:47:
Т.е. надо бы включить колонку "UserID" (без этого включения в индекс не попадаем). Так всегда было в MS SQL?

Без этого в индекс попадаем, но требуется ещё bookmark lookup записи для извлечения UserId. Стоимость этих двух операций может быть выше стоимости сканирования таблицы. Опция Include появилась в SQL Server 2005.

JohnyDeath писал(а) 25. Августа 2010 :: 08:47:
И еще вопрос: как правильно выбирать порядок столбцов, входящих в индекс?

Обычно поля, дающие бóльшую избирательность, идут в начале, как и советует SSMS. Но тут стóит ещё посмотреть, будут ли у тебя запросы с отбором только по BaseId.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #5 - 25. Августа 2010 :: 09:10
Печать  
Цитата:
Стоимость этих двух операций может быть выше стоимости сканирования таблицы.

Во всей таблице было 10000 записей. Столбцов - 9 шт. Неужели полное сканирование таблице дешевле поиска столбца?

Про поля в индексе:
у меня в отборе BaseId будет всегда (это ИД базы), т.е. это поле должно быть во всех индексах и желательно самое последнее, т.к. остальные поля дают бОльшую избирательность.
Я правильно мыслю?
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #6 - 25. Августа 2010 :: 09:27
Печать  
JohnyDeath писал(а) 25. Августа 2010 :: 09:10:
Во всей таблице было 10000 записей. Столбцов - 9 шт. Неужели полное сканирование таблице дешевле поиска столбца?

Важно ещё, сколько, по данным статистики, будет отобрано записей. Для получения точного ответа этот вопрос лучше задать разработчикам SQL Server  Подмигивание т.к. точная формула расчёта стоимости в BOL отсутствует. Хочешь индекс - укажи его хинтом.

JohnyDeath писал(а) 25. Августа 2010 :: 09:10:
Про поля в индексе:
у меня в отборе BaseId будет всегда (это ИД базы), т.е. это поле должно быть во всех индексах и желательно самое последнее, т.к. остальные поля дают бОльшую избирательность.
Я правильно мыслю?

Вопрос не в том, будет ли в отборе BaseId, а в том, будут ли отборы по BaseId без ObjectFullId? Если нет - используй рекомендацию SSMS. И да - ты мыслишь правильно.  Улыбка
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Berck
Junior Member
**
Отсутствует



Сообщений: 66
Местоположение: Москва
Зарегистрирован: 17. Июля 2007
Пол: Мужской
Re: правильное создание индексов
Ответ #7 - 26. Августа 2010 :: 11:13
Печать  
А кластерный индекс то у тебя создан по таблице?
попробуй
Код
Выбрать все
CREATE CLUSTERED INDEX [idx_ObjectFullID] ON [dbo].[Events]
(
	[BaseID] ASC,
	[ObjectFullID] ASC
) 


и никаких INCLUDE ([UserID]) уже не надо.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #8 - 26. Августа 2010 :: 11:31
Печать  
Berck писал(а) 26. Августа 2010 :: 11:13:
А кластерный индекс то у тебя создан по таблице?
попробуй
Код
Выбрать все
CREATE CLUSTERED INDEX [idx_ObjectFullID] ON [dbo].[Events]
(
	[BaseID] ASC,
	[ObjectFullID] ASC
) 


и никаких INCLUDE ([UserID]) уже не надо.


из (0) не следует что такие записи не могут повторяться.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #9 - 26. Августа 2010 :: 12:00
Печать  
Z1 писал(а) 26. Августа 2010 :: 11:31:
из (0) не следует что такие записи не могут повторяться.

Ну.. с точки зрения пользователя, кластерный индекс в SQL Server не обязан быть уникальным..  Улыбка
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #10 - 26. Августа 2010 :: 12:02
Печать  
berezdetsky писал(а) 26. Августа 2010 :: 12:00:
Z1 писал(а) 26. Августа 2010 :: 11:31:
из (0) не следует что такие записи не могут повторяться.

Ну.. с точки зрения пользователя, кластерный индекс в SQL Server не обязан быть уникальным..  Улыбка

это то да но в 99 случаях из 100 кластерный индекс строиться на уникальных данных.
  
Наверх
 
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: правильное создание индексов
Ответ #11 - 26. Августа 2010 :: 12:22
Печать  
Связка [BaseID]-[ObjectFullID] в этой таблице может повторяться бесконечное число раз.
Пока добавил в INCLUDE столбцы, которые мне вроде как должны понадобиться, и успокоился.
  
Наверх
 
IP записан
 
leshik
1c++ donor
Отсутствует



Сообщений: 820
Местоположение: Пятигорск
Зарегистрирован: 22. Апреля 2007
Пол: Мужской
Re: правильное создание индексов
Ответ #12 - 26. Августа 2010 :: 12:55
Печать  
Дааа INCLUDE определенно рулит Улыбка
http://sql.ru/forum/actualthread.aspx?tid=784754
  
Наверх
IP записан
 
Berck
Junior Member
**
Отсутствует



Сообщений: 66
Местоположение: Москва
Зарегистрирован: 17. Июля 2007
Пол: Мужской
Re: правильное создание индексов
Ответ #13 - 27. Августа 2010 :: 12:00
Печать  
Z1 писал(а) 26. Августа 2010 :: 12:02:
berezdetsky писал(а) 26. Августа 2010 :: 12:00:
Z1 писал(а) 26. Августа 2010 :: 11:31:
из (0) не следует что такие записи не могут повторяться.

Ну.. с точки зрения пользователя, кластерный индекс в SQL Server не обязан быть уникальным..  Улыбка

это то да но в 99 случаях из 100 кластерный индекс строиться на уникальных данных.

"В SQL Server кластерный индекс является уникальным индексом по определению. Это означает что все ключи записей должны быть уникальные. Если существуют записи с одинаковыми значениями, SQL Server делает их уникальными, добавляя номера из внутреннего (невидимого снаружи) счетчика."
http://www.sql.ru/articles/mssql/03013101indexes.shtml#3

ИМХО INCLUDE - это решение для частного случая, когда под определенный очень важный запрос требуется свой индекс и некий набор полей.
А когда любое обращение к таблице делает фильтрацию по [BaseID] и [ObjectFullID] лучше создать кластерный индекс.

"запись может быть найдена либо по row ID либо по кластерному ключу. Это важное замечание, поскольку row ID или кластерный ключ будут сохраняться внутри не кластерного индекса и использоваться для получения реальных данных из записей."

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать