powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Перестройка некластерных индексов при создании кластероного
18 сообщений из 18, страница 1 из 1
Перестройка некластерных индексов при создании кластероного
    #39908627
Evgi1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нужно одним запросом вставить огромное количество записей в таблицу.

Делаю так:
1. Удаляю кластерный индекс.
2. Отключаю некластерные индексы.
3. Вставляю данные: insert into with(tablock)
3. Создаю кластерный индекс
4. Включаю некластерные индексы

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

Можно ли как то отключить перестройку отключенных некластерных индексов при удалении кластерного?
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908634
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Evgi1980,

Грохните на пункте 2 некластерные вместо отключения. У вас все равно при включении индекс заново создается.

А лучше сначала грохнуть некластерные, потом кластерный. Залить данныы, создать кластер, создать все некластерные

Адд: Или лить вообще в кластерный, не факт что в непустую кучу будет быстрее
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908645
Evgi1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
чтобы грохнуть некластерные нужно знать их текст создания, а в это влезать не хотелось бы, тем и хорошо было их отключение а затем включение
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908649
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Evgi1980,

ну так при кластерном индексы ссылаются на ключ кластерного, а при некластерном - на страницы кучи. Индексы обязательно должны быть перестроены, созданы заново, другими словами. Можно удалить, но предварительно надо создать скрипты индексов. Вообще такие вещи лучше делать в проекте базы, студия сама всё автоматизирует.
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908653
Evgi1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов,

это все понятно, но отключенные то зачем при этом перестраивать и включать, их же все равно нужно будет перестроить при их включении
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908656
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Evgi1980
чтобы грохнуть некластерные нужно знать их текст создания
Чтобы удалить индекс нужно знать только его имя.
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908805
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Evgi1980
чтобы грохнуть некластерные нужно знать их текст создания
Чтобы удалить индекс нужно знать только его имя.
По всей видимости, ОР имел в виду, что все это нужно знать для их последующего пересоздания, когда заливка закончена.

Evgi1980,

Заливки лучше делать в отдельные таблицы, с минимумом индексов (например, с кластерным PK на identity) или вообще без оных, по обстоятельствам. Потом уже смотреть, какая часть этих данных реально нужна. Будете заливать напрямую в нагруженную таблицу на боевой базе - пользователи выстроятся в очередь на блокировках, мало не покажется.
Для заливки в промежуточные таблицы соотв. индексы можно и захардкодить (если льете посредством SSIS, то в пакете, ну или в базе можно отдельную таблицу создать со всеми CREATE INDEX для заливаемых таблиц). Понятно, что это надо будет поддерживать...
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908868
Фотография PsyMisha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

Да, и лучше не хардкодить имена, а пройтись по всем текущим в курсоре - генерить динамический t-sql в цикле
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908872
Фотография PsyMisha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ennor Tiegael,

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

Писал когда-то такую процедурку
При желании можно поменять там ALTER INDEX DISABLE на DROP INDEX


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
CREATE PROCEDURE [dbo].[usp_Process_NCIndexes_On_Table]
--EXEC dbo.usp_Process_NCIndexes_On_Table @Table_Name = 'sysdiagrams', @Schema_Name = 'dbo', @Action_Type = 'disable'
@Action_Type AS NVARCHAR(MAX),
@Table_Name AS NVARCHAR(MAX),
@Schema_Name AS NVARCHAR(10)

AS
BEGIN
-- ###########################
IF NOT (LOWER(@Action_Type) = 'enable' OR LOWER(@Action_Type) = 'disable')
	BEGIN
		SELECT 'Action type provided has incorrect value. Please call the procedure either with ''enable'' or ''disable'' parameter'
		GOTO BRANCH_END
	END
-- ###########################
	
DECLARE @SQLCMD AS NVARCHAR(MAX)
DECLARE @Final_SQL AS NVARCHAR(MAX)
DECLARE @Index_Name AS NVARCHAR(2000)

--DECLARE @Table_Name AS NVARCHAR(100)
--SET @Table_Name = 'sysdiagrams'
--DECLARE @Schema_Name AS NVARCHAR(10)
--SET @Schema_Name = 'dbo'

SET @SQLCMD = 'DECLARE indexes_cursor CURSOR READ_ONLY FOR 
SELECT i.name AS [Index Name]
FROM sys.tables AS tbl
INNER JOIN sys.indexes AS i ON (i.index_id > 0 and i.is_hypothetical = 0) AND (i.object_id=tbl.object_id)
WHERE i.type = 2 --NC INDEX TYPE
AND tbl.name = ''' + @Table_Name + ''' AND schema_name(schema_id) = ''' + @Schema_Name + ''''

EXEC sp_executesql @SQLCMD

IF @Action_Type = 'enable' 
	BEGIN
		GOTO BRANCH_ENABLE
	END
ELSE
	BEGIN
		GOTO BRANCH_DISABLE
	END
	
-- ############
BRANCH_DISABLE:
OPEN indexes_cursor
FETCH NEXT FROM indexes_cursor INTO @Index_Name

WHILE @@FETCH_STATUS = 0
	BEGIN
		SET @Final_SQL = 'ALTER INDEX [' + @Index_Name + '] ON ' + '[' + @Schema_Name + '].[' + @Table_Name + ']' + ' DISABLE'
		--EXEC @Final_SQL
		PRINT @Final_SQL
			FETCH NEXT FROM indexes_cursor INTO @Index_Name
	END

CLOSE indexes_cursor
DEALLOCATE indexes_cursor
GOTO BRANCH_END

-- ############
BRANCH_ENABLE:
OPEN indexes_cursor
FETCH NEXT FROM indexes_cursor INTO @Index_Name

WHILE @@FETCH_STATUS = 0
	BEGIN
		SET @Final_SQL = 'ALTER INDEX [' + @Index_Name + '] ON ' + '[' + @Schema_Name + '].[' + @Table_Name + ']' + ' REBUILD WITH (FILLFACTOR=100, PAD_INDEX=ON)'
		--EXEC @Final_SQL
		PRINT @Final_SQL
			FETCH NEXT FROM indexes_cursor INTO @Index_Name
	END

CLOSE indexes_cursor
DEALLOCATE indexes_cursor
GOTO BRANCH_END

BRANCH_END:
	PRINT 'Done'
END
GO


...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908937
entrypoint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Evgi1980,

Всегда будут перестраиваться
согласно документации

авторУказатель из строки индекса в некластеризованном индексе, который указывает на строку данных, называется указателем строки . Структура указателя строки зависит от того, хранятся ли страницы данных в куче или в кластеризованной таблице. Для кучи указатель строки является указателем на строку. Для кластеризованной таблицы указатель строки данных является ключом кластеризованного индекса .
https://docs.microsoft.com/ru-ru/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described?view=sql-server-ver15


Т.е. при удалении кластеризованного индекса изменяется указатель строки в некластеризованном индексе
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908940
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
entrypoint,

это понятно, непонятен смысл перестройки отключенного индекса (если такая перестройка действительно имеет место). Отключенный индекс должен быть построен заново при включении.
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39908941
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PsyMisha,

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

То, что привели вы - извините, детский сад. Почему у вас все индексы пересоздаются с опциями FILLFACTOR=100, PAD_INDEX=ON? Других в вашей вселенной не бывает в принципе? Как насчет XML (primary / secondary), sparse, columnstore (clustered / nonclustered)? Уникальных индексов / констрейнтов вы тоже не используете, я так понимаю.

Я как-то писал процедуру для динамической реорганизации / ребилда индексов с плавающим fragmentation threshold, зависящим от размера индекса. Даже без учета XML и sparse (мне они были не нужны), получилась простыня где-то на 1000 строк. И то, после 2016 версии я к ней не прикасался, т.к. не админил толком с тех пор. Чтобы внести туда нововведения 2017+, наверняка придется попотеть.

Именно поэтому я и предложил хранить DDL индексов в базе, а не генерировать его на лету. Потому что я уже проходил через это, и знаю, сколько усилий нужно вложить, чтобы написать действительно надежный, качественный скриптер :) Не говоря уже о том, что результат работы этого скриптера автору таки придется где-то хранить, пока таблица заливается новыми данными. Процесс запросто может занять больше одного дня, коннект - отвалиться от сервера, RDP-сессия - быть принудительно выгруженной, рабочий комп - перезагрузиться, и т.д. Так что это приведет только к увеличению ручной работы, но никак не к уменьшению оной.
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39909035
Фотография PsyMisha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ennor Tiegael

То, что привели вы - извините, детский сад. Почему у вас все индексы пересоздаются с опциями FILLFACTOR=100, PAD_INDEX=ON


не извиню. :)
Я предложил Фреймворк решения - нужны всякие штучки по XML и иже с ними - можно взять напильник и допилить
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39909144
Фотография PsyMisha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ennor Tiegael

предложил хранить DDL индексов в базе, а не генерировать его на лету


В целом, наверное, это имеет определенный смысл, просто по опыту - поскольку сильно и частенько меняется ситуация "наверху" БД - в частности - пример про DWH и клиентские BI-отчеты - сегодня пользователи активно пользуют конкретный отчет, а завтра и впоследствии - он уже внезапно может стать неактуальным - сменились требования, пришел новый функционал из коробки ИС-источника, уволился сотрудник - бизнес-аналитик, который его использовал как рабочий инструмент на каждодневной основе, или вообще пользователи попросили новую колонку в графический элемент управления добавить, а другую - убрать - и все, индекс лежит заброшенный, никем не используемый, последний раз по статистике использования оптимизатор его выбирал n-месяцев назад, - и посему индекс лишь увеличивает сопровождение и ненужно обновляется и при этом не читается - так вот - отслеживать такое конечно можно, - наверное, какие-нибудь data stewards этим могут заниматься, ну или DBA, если он сознательный и процесс сопровождения БД хорошо построен методологически, - тогда, наверное, можно DDL так сопровождать

Но я, лично, за то всегда, чтобы человеческий фактор всегда исключать такой - и генерить все динамикой, да и тот же DDL если нужно так же динамикой
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39909148
Фотография PsyMisha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ennor Tiegael,

Вот, кстати, пример скриптера-генератора-советчика недостающих индексов, который DDL генерит

Понятно, что втупую копировать DDL из его советов и тут же его копипастить в студию и выполнять - грубый и сомнительный шаг - но тем не менее, как подход
Можно взять, к примеру, часть этого скрипта за основу, - сам аспект, как он по колонкам создает поля в CREATE INDEX, и натравливать на целевые объекты-таблицы, с целью вычленить из них колонки текущих некластерных индексов, и сохранять полученное значение в колонке со стейтментами в служебной таблице. Потом - через EXEC sp_executesql выполнять в динамике


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
USE master


DECLARE @DBName AS NVARCHAR(MAX)
SET @DBName = 'NPM_DB'

SELECT TOP 20
CONVERT (decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans)) AS improvement_measure, 
'CREATE INDEX missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle) + ' ON ' + mid.statement + ' (' + ISNULL (mid.equality_columns,'') + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END + ISNULL (mid.inequality_columns, '') + ')' + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement, 
object_name(mid.[object_id],
mid.database_id) as objectname, 
migs.unique_compiles,
migs.user_seeks,
migs.user_scans,
migs.last_user_seek,
migs.last_user_scan,
migs.avg_user_impact

FROM sys.dm_db_missing_index_groups mig 
INNER JOIN sys.dm_db_missing_index_group_stats migs 
ON migs.group_handle = mig.index_group_handle 
INNER JOIN sys.dm_db_missing_index_details mid 
ON mig.index_handle = mid.index_handle 
 
WHERE CONVERT (decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans)) > 10 
AND mid.database_id = DB_ID(@DBName)
--AND mid.statement LIKE '%vendor%'
--AND object_name(mid.[object_id], mid.database_id) not like '%2019%'


order by 5 desc

--ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC


...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39909169
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PsyMisha,

DWH это другой случай, уж там лить точно надо в Staging, а все остальное - от лукавого.
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39909173
Фотография PsyMisha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ennor Tiegael,

Ну тип того :)

или мб не в схему [stage]. - напрямую, - все-таки - она больше для интеграционных процессов предназначена, а в какую-нибудь [system]. - там архитектурно хранить всю обвязку, инфраструктуру вокруг слоя витрин, - вобщем - провода и гайки под капотом :)
...
Рейтинг: 0 / 0
Перестройка некластерных индексов при создании кластероного
    #39910680
Фотография Mind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Evgi1980,

Вы сначала удаляете кластерный, а потом выключаете некластерные, вот они и перестраиваются.

"I like to move it move it"

У вас слишком много перестроений причем не только некластерных индексов, но и всей таблицы. Зачем??
Уберите пункты 1 и 3 и будет вам счастье.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Перестройка некластерных индексов при создании кластероного
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]