sql server - SQL query optimization -
i trying find out script can me in data density of dbs. point figure out query , need problem query takes ever. works find small dbs, doesn't happen lot. looking kind of optimization or ideas me. script:
declare cur cursor select db_name() databasename ,s.[name] schemaname ,t.[name] tablename ,c.[name] columnname ,'[' + db_name() + ']' + '.[' + s.name + '].' + '[' + t.name + ']' fullqualifiedtablename ,d.[name] datatype sys.schemas s inner join sys.tables t on s.schema_id = t.schema_id inner join sys.columns c on t.object_id = c.object_id inner join sys.types d on c.user_type_id = d.user_type_id d.name '%int%' or d.name '%float%' or d.name '%decimal%' or d.name '%numeric%' or d.name '%real%' or d.name '%money%' or d.name '%date%' or d.name '%datetime%' , is_identity = 0 open cur fetch next cur @databasename ,@schemaname ,@tablename ,@columnname ,@fullyqualifiedtablename ,@datatype while @@fetch_status = 0 -- fetch statement successful. begin declare @sql varchar(max) = null set @sql = ' select ''' + @databasename + ''' databasename, ''' + @schemaname + ''' tablename, ''' + @tablename + ''' schemaname, ''' + @columnname + ''' columnname, ''' + @datatype + ''' columnname, (select max(' + @columnname + ') ' + @fullyqualifiedtablename + ' (nolock)) maxvalue, (select min(' + @columnname + ') ' + @fullyqualifiedtablename + ' (nolock)) minvalue, (select count(*) ' + @fullyqualifiedtablename + ' (nolock)) countvalue, (select count(*) ' + @fullyqualifiedtablename + ' ' + @columnname + ' not null ) notnullcount, (select 0 ' + @fullyqualifiedtablename + ') datadensity' print @sql
the following script give me max, min, count, notnullcount , data density every , each column form declared types above. u can imagine db 70 tables , each table has 30-50 columns.... running script take ever.
you should try , avoid using cursors, query give list of select queries can copy , paste data require. note have removed sub selects not required:
select 'select ''' + db_name() + ''' databasename, ''' + s.name + ''' schemaname, ''' + t.name + ''' tablename, ''' + c.name + ''' columnname, ''' + d.name + ''' columnname,' + 'max([' + c.name + ']) maxvalue,' + 'min([' + c.name + ']) minvalue,' + 'count(*) countvalue,' + 'count([' + c.name + ']) notnullcount,' + 'cast(count(distinct [' + c.name + ']) float) / count([' + c.name + ']) datadensity ' + 'from [' + db_name() + '].[' + s.name + '].[' + t.name + '] (nolock)' sys.schemas s inner join sys.tables t on s.schema_id = t.schema_id inner join sys.columns c on t.object_id = c.object_id inner join sys.types d on c.user_type_id = d.user_type_id d.name '%int%' or d.name '%float%' or d.name '%decimal%' or d.name '%numeric%' or d.name '%real%' or d.name '%money%' or d.name '%date%' or d.name '%datetime%' , is_identity = 0
this give list of select statements in following form:
select 'mydb' databasename, 'dbo' schemaname, 'mytable' tablename, 'id' columnname, 'int' columnname,max([id]) maxvalue,min([id]) minvalue,count(*) countvalue,count([id]) notnullcount,cast(count(distinct [id]) float) / count([id]) datadensity [mydb].[dbo].[mytable] (nolock)
of course sql server stores these sorts of statistics useful columns, can find ones has using:
exec sp_helpstats 'mytable', 'all'
then using list of statistics returned such as:
_wa_sys_00000014_004fb3fb id
to actual stats using:
dbcc show_statistics('mytable','_wa_sys_00000002_004fb3fb')
this return data like:
name updated rows rows sampled steps density average key length string index filter expression unfiltered rows _wa_sys_00000002_004fb3fb jan 8 2017 8:01pm 16535 16535 200 0.2493151 4.459389 no null 16535
and
all density average length columns 0.0006038647 4.459389 effectivedate
and rowset showing histogram of values.
you can automatically generate these dbcc
commands using:
select 'dbcc show_statistics([' + object_name(s.object_id) + '],''' + s.name + ''')' sys.stats s inner join sys.stats_columns sc on s.object_id = sc.object_id , s.stats_id = sc.stats_id inner join sys.columns c on sc.object_id = c.object_id , sc.column_id = c.column_id s.name '_wa%' order s.stats_id, sc.column_id;
Comments
Post a Comment