1+ /* #info
2+
3+ # Autor
4+ Rodrigo Ribeiro Gomes
5+
6+ # Detalhes
7+ Esse script foi uma tentativa de estimar o tempo necessário para criar um índice.
8+ Me lembro de ter usado algumas vezes em produção e ter resultados muitos próximos do real.
9+ A ideia é muito simples:
10+ - Dado uma tabela (@TableName) e uma lista de colunas (@TestCols) que quero indexar
11+ - Crio uma cópia dessa tabela com uma amostra de linhas (parâmetro @TestSize)
12+ - Então, crio o índice na cópia, com as colunas desejada e mensuro o tempo que levou.
13+ - No final, faço uma regra de três simples para estimar para o total de linhas da tabela.
14+
15+
16+
17+
18+ */
19+
20+ DECLARE
21+ @TableName sysname
22+ ,@TestSize bigint = 50000
23+ ,@TestCols nvarchar (max ) = NULL
24+
25+ SET @TableName = ' Posts'
26+ set @TestCols = ' Id'
27+
28+ -- --
29+ set nocount on ;
30+
31+ IF OBJECT_ID (@TableName) IS NULL
32+ BEGIN
33+ RAISERROR (' Invalid table %s' ,16 ,1 ,@TableName);
34+ RETURN ;
35+ END
36+
37+ if @TestCols is null
38+ BEGIN
39+ RAISERROR (' Invalid cols' ,16 ,1 );
40+ RETURN ;
41+ END
42+
43+ DECLARE
44+ @CopyTableName sysname
45+ ,@sql nvarchar (MAX )
46+ ,@TotalSize bigint = 0
47+ ,@StartTime datetime
48+ ,@EndTime datetime
49+ ,@TotalCreateTime bigint
50+ ,@TableSize bigint
51+
52+ SET @CopyTableName = ' zzzIndexCreationEstimate_'+ replace (@TableName,' .' ,' _' )
53+
54+ SET @sql = ' SELECT '+ @TestCols+ ' INTO '+ @CopyTableName+ ' FROM '+ @TableName+ ' WHERE 1 = 2' +
55+ ' UNION ALL SELECT '+ @TestCols+ ' FROM '+ @TableName+ ' WHERE 1 = 2'
56+ exec (@sql)
57+
58+ IF @@ERROR != 0
59+ RETURN ;
60+
61+
62+ RAISERROR (' Test table %s created! To drop run: DROP TABLE %s' ,0 ,1 ,@CopyTableName,@CopyTableName) with nowait ;
63+
64+ SET @sql = ' INSERT INTO '+ @CopyTableName+ ' SELECT '+ @TestCols+ ' FROM '+ @TableName+ ' TABLESAMPLE(10000 ROWS)'
65+ exec (@sql)
66+
67+ raiserror (' Loading copy Table...' ,0 ,1 ) with nowait ;
68+ while @TotalSize < @TestSize
69+ begin
70+
71+ SELECT @TotalSize = sum (rows ) FROM sys .partitions p where p .object_id = object_id (@CopyTableName)
72+ exec (@sql)
73+ end
74+
75+ set @sql = ' create index ixTest on '+ @CopyTableName+ ' ('+ @TestCols+ ' )' ;
76+ raiserror (' Creating test index on %s' ,0 ,1 ,@CopyTableName)
77+ set @StartTime = getdate ();
78+ exec (@sql);
79+ set @EndTime = getdate ();
80+ select @StartTime,@EndTime
81+ set @TotalCreateTime = ISNULL (NULLIF (datediff (ms,@StartTime,@EndTime),0 ),1 )
82+
83+
84+
85+ SELECT @TableSize = sum (rows ) FROM sys .partitions p where p .object_id = object_id (@TableName)
86+ and p .index_id <= 1
87+
88+ select CopyTotalRows = @TotalSize
89+ ,CopyCreationDurationMs = @TotalCreateTime
90+ ,RealTotalRows = @TableSize
91+ ,RealCreationEstimationMs = (@TotalCreateTime* @TableSize)/ @TotalSize
92+
93+
94+
95+ select DropThisTableToEnd = ' drop table '+ @CopyTableName;
0 commit comments