Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Один Индекс(INCLUDE на все поля)  [new]
RomanH
Member

Откуда:
Сообщений: 539
Доброго времени суток.
Имеется таблица:
CREATE TABLE [dbo].[MyTable]
( 
	[Id]	INT IDENTITY(1,1) NOT NULL,		
	[F1]	INT NOT NULL,
	[F2]	INT NOT NULL,
	[F3]	INT NOT NULL,
	[Date]	DATETIME NOT NULL,
	[D1]	INT NOT NULL,
	[D2]	INT NOT NULL,
	[D3]	INT NOT NULL,
	[D4]	INT NOT NULL,
	[D5]	INT NOT NULL,
	[D6]	INT NOT NULL,
	
	CONSTRAINT [PK_MyTable] PRIMARY KEY NONCLUSTERED ([Id]),	
	CONSTRAINT [UQ_MyTable$F1$F2$Date] UNIQUE CLUSTERED ([F1],[F2],[Date]),
	--CONSTRAINT [FK_MyTable$F1] FOREIGN KEY(F1) REFERENCES TF1(Id),	
	--CONSTRAINT [FK_MyTable$F2] FOREIGN KEY(F2) REFERENCES TF2(Id),	
	--CONSTRAINT [FK_MyTable$F3] FOREIGN KEY(F3) REFERENCES TF3(Id),
)

Оптимизатор для разных запросов предлагает создать следующие индексы:
CREATE NONCLUSTERED INDEX IX1
ON [dbo].[MyTable] ([Date])
INCLUDE ([F1],[F3],[D1],[D2],[D3])

CREATE NONCLUSTERED INDEX IX2
ON [dbo].[MyTable] ([Date])
INCLUDE ([F1],[F2],[D1],[D2],[D3])

CREATE NONCLUSTERED INDEX IX3
ON [dbo].[MyTable] ([Date])
INCLUDE ([F1],[D1],[D2],[D3],[D4])

CREATE NONCLUSTERED INDEX IX4
ON [dbo].[MyTable] ([Date])
INCLUDE ([F1],[D1],[D2],[D3],[D4],[D5],[D6])


Мне нужно минимизировать кол-во индексов в этой таблице.
Вопрос:
Можно ли в этом случае создать один общий индекс и в INCLUDE запихать все необходимые поля?
Или лучше создать как советует оптимизатор?
Вот так:
CREATE NONCLUSTERED INDEX IX_COMMON
ON [dbo].[MyTable] ([Date])
INCLUDE ([F1],[F2],[F3],[D1],[D2],[D3],[D4],[D5],[D6])


Хочется чтобы и SELECT'ы быстро отрабатывали и при INSERT'е перестраивалось как можно меньше индексов.
Спасибо!
28 янв 14, 18:32    [15484186]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
NickAlex66
Member

Откуда:
Сообщений: 319
RomanH,

Может подправить кластерный индекс (если др запросы не "против") и тогда ничего др делать не придется?
28 янв 14, 18:48    [15484265]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31824
RomanH
Можно ли в этом случае создать один общий индекс и в INCLUDE запихать все необходимые поля?
Или лучше создать как советует оптимизатор?
Можно вместо
CONSTRAINT [UQ_MyTable$F1$F2$Date] UNIQUE CLUSTERED ([F1],[F2],[Date])

сделать
CONSTRAINT [UQ_MyTable$F1$F2$Date] UNIQUE CLUSTERED ([Date],[F1],[F2])


Конечно, взвесив всё остальное - запросы по [F1],[F2] и как делаются вставки.
28 янв 14, 18:50    [15484275]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
uiwehiquwef
Guest
автор, это тебе оптимизатор предлагает. потому что, один кластерник - слишком толсто. один индекс на одно поле и все в инклюд - слишком толсто.

он предлагает разные варианты include, потому что индексы тоньше. он хочет помочь чтению. но да, с записью будет жопа.

ps. я о толсто/тонко с позиции i/o
28 янв 14, 20:06    [15484591]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
Индекс с include на всё (или почти все) поля от Оптимайзера,
означает очень толстый намёк на то, что ему нужен "другой" кластерный индекс.
29 янв 14, 20:51    [15490949]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31824
EvAlex
Индекс с include на всё (или почти все) поля от Оптимайзера,
означает очень толстый намёк на то, что ему нужен "другой" кластерный индекс.
Оптимизатор как раз такого не предлагает :-)

Для запросов, очевидно, лучше всего сделать именно эту кучку индексов, которые предлагает оптимизатор, но ТС пытается найти наилучшее соотношение для выборок и вставок...
29 янв 14, 22:14    [15491244]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Сервер как раз очень любит предложить индекс в который будут включены все поля. Есть даже где-то рекомендация (то ли от МС, то ли от Пола Рэндала - лень искать ссылку - короче, авторитетного источника) в которой сказано, что не нужно вслепую создавать индексы по предложению Missing indexes. Кроме того есть баг, что сервер предлагает создать уже те индексы, которые уже есть (тоже, вроде, у Рэндала описано)

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

Зная свою нагрузку, создавайте индексы, не бойтесь! Но, осторожно! Мониторьте количество чтений и записи в индексах при помощи DMW, смотрите как "пациент" реагирует на новый индекс. Есть отличные диагностические запросы SQL Server Diagnostic Information Queries for January 2014

Анализируя данные Missing DMV я стараюсь не создать каждый индекс, но сделать некий общий знаменатель, один-два индекса, которые подойдут под большинство требований. Как такое сделать - лучше всего почитать про индексы, посмотреть доклад Димы Короткевича [url=]Индексы и все, все, все (Часть 1)[/url] (там несколько частей).

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

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

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

Удачи =)
29 янв 14, 23:02    [15491422]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
SomewhereSomehow,

Ого! Как ютюб вставился, я не ожидал такого, думал будет просто ссылка =))
Промоушен Диме Короткевичу засчитан =)
29 янв 14, 23:03    [15491425]     Ответить | Цитировать Сообщить модератору
 Re: Один Индекс(INCLUDE на все поля)  [new]
RomanH
Member

Откуда:
Сообщений: 539
Добрый день!
Переделал кластерный индекс, как посоветовал:
alexeyvg
сделать
CONSTRAINT [UQ_MyTable$F1$F2$Date] UNIQUE CLUSTERED ([Date],[F1],[F2])



alexeyvg, спасибо!

Остальные индексы не потребовались, т.к. в запросах вида:
SELECT T.F1...
FROM MyTable T
INNER JOIN #F1 ON #F1.Id = T.F1
INNER JOIN #F2 ON #F2.Id = T.F2
WHERE T.Date BETWEEN @D1 AND @D2
GROUP BY T.F1...

В основном используется Clustered Seek. По времени выполнения все устраивает(пришлось проверить все запросы в которых участвует эта таблица).

Вставка в таблицу выполняется в 2 раза быстрее!!! Это и понятно, т.к. имеем дело с историческими данными.
Представляю что происходило со страницами с предыдущим кластерным индексом. Ужос!
Да еще и перестроение 4 индексов....

SomewhereSomehow
Удачи =)

Спасибо! Она мне пригодилась!
Обошлось как говориться малой кровью. В следующий раз при создании кластерного индекса буду учитывать полученный опыт.
3 фев 14, 11:19    [15508939]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить