2017-08-18 20 views
0

DBのデータ密度に役立つスクリプトを見つけようとしています。ポイントは私はすでにクエリを把握していますが、私は何が必要ですが、問題はクエリが永遠にかかることです。それは小さなDBのために働くが、それはあまり起こらない。 私は最適化や、私を助けるためのアイデアを探しています。 スクリプト:SQLクエリの最適化

DECLARE Cur CURSOR 
FOR 
SELECT DB_Name() AS DatabaseName 
,s.[name] AS SchemaName 
,t.[name] AS TableName 
,c.[name] AS ColumnName 
,'[' + DB_Name() + ']' + '.[' + s.NAME + '].' + '[' + T.NAME + ']' AS FullQualifiedTableName 
,d.[name] AS DataType 
FROM 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 
WHERE d.NAME LIKE '%int%' 
OR d.NAME LIKE '%float%' 
OR d.NAME LIKE '%decimal%' 
OR d.NAME LIKE '%numeric%' 
OR d.NAME LIKE '%real%' 
OR d.NAME LIKE '%money%' 
OR d.NAME LIKE '%date%' 
OR d.NAME LIKE '%datetime%' 

AND is_identity = 0 

OPEN Cur 

FETCH NEXT 
FROM Cur 
INTO @DatabaseName 
,@SchemaName 
,@TableName 
,@ColumnName 
,@FullyQualifiedTableName 
,@DataType 


WHILE @@FETCH_STATUS = 0 -- The FETCH statement was successful. 
BEGIN 
DECLARE @SQL VARCHAR(MAX) = NULL 

SET @SQL = ' Select ''' + @DatabaseName + ''' AS DatabaseName, ''' + 
@SchemaName + ''' AS TableName, 
    ''' + @TableName + ''' AS SchemaName, 
    ''' + @ColumnName + ''' AS ColumnName, 
    ''' + @DataType + ''' AS ColumnName, 

    (Select MAX(' + @ColumnName + ') from ' + @FullyQualifiedTableName + ' with (nolock)) 
    AS MaxValue, 
    (Select MIN(' + @ColumnName + ') from ' + @FullyQualifiedTableName + ' with (nolock)) 
    AS MinValue, 
    (Select COUNT(*) from ' + @FullyQualifiedTableName + ' with (nolock)) 
    AS CountValue, 
    (Select COUNT(*) from ' + @FullyQualifiedTableName + ' Where ' + @ColumnName + ' IS NOT NULL) 
    AS NotNULLCount, 
    (Select 0 from ' + @FullyQualifiedTableName + ') 
    AS DataDensity' 

PRINT @SQL 

次のスクリプトは、すべてのための私のMAX、MIN、COUNT、NotNULLCountとデータ密度を与えるだろうし、各列は上記の宣言された型を形成します。しかし、あなたは70のテーブルと各テーブルのDBが30-50の列を持っていると想像することができます.... このスクリプトを実行すると永遠にかかるでしょう。

+0

質問は、スキーマをスクリプト大型しようとしているDDL、テストデータdata..ifテストと一緒に関与してテーブルのDMLを含める必要がありますし、:

あなたは自動的に使用して、これらのDBCCコマンドを生成することができますテーブルの統計情報( '右クリックデータベース - >スクリプト生成 - >特定のデータベースオブジェクトを選択 - >次の画面で詳細を選択し、統計情報を選択)'を選択し、問題に貼り付けます。サーバのバージョンを貼り付けることも実際には良い解決策です – TheGameiswar

答えて

1

カーソルを使用しないでください。このクエリは、必要なデータを取得するためにコピー&ペーストできる選択クエリのリストを提供します。それらが必要とされていないようにも注意してください私は、サブ選択を削除した:の

コースSQL Serverの店の
Select 'MyDB' AS DatabaseName, 'dbo' AS SchemaName, 'MyTable' AS TableName, 'ID' AS ColumnName, 'int' AS ColumnName,MAX([ID]) AS MaxValue,MIN([ID]) AS MinValue,COUNT(*) AS CountValue,COUNT([ID]) AS NotNullCount,CAST(COUNT(DISTINCT [ID]) AS float)/COUNT([ID]) AS DataDensity from [MyDB].[dbo].[MyTable] with (nolock) 

これらの種類:

SELECT 'Select ''' + DB_Name() + ''' AS DatabaseName, ''' + s.Name + ''' AS SchemaName, ''' + t.Name + ''' AS TableName, ''' + c.Name + ''' AS ColumnName, ''' + d.Name + ''' AS ColumnName,' + 
'MAX([' + c.Name + ']) AS MaxValue,' + 
'MIN([' + c.Name + ']) AS MinValue,' + 
'COUNT(*) AS CountValue,' + 
'COUNT([' + c.Name + ']) AS NotNullCount,' + 
    'CAST(COUNT(DISTINCT [' + c.name + ']) AS float)/COUNT([' + C.Name + ']) AS DataDensity ' + 
    'from [' + DB_Name() + '].[' + s.Name + '].[' + t.name + '] with (nolock)' 
FROM 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 
WHERE d.NAME LIKE '%int%' 
OR d.NAME LIKE '%float%' 
OR d.NAME LIKE '%decimal%' 
OR d.NAME LIKE '%numeric%' 
OR d.NAME LIKE '%real%' 
OR d.NAME LIKE '%money%' 
OR d.NAME LIKE '%date%' 
OR d.NAME LIKE '%datetime%' 
AND is_identity = 0 

これはあなたの次の形式でselect文のリストが表示されます便利な列の統計、あなたはそれを使用しているものを見つけることができます:

EXEC SP_HELPSTATS 'MyTable', 'ALL' 

を次に統計のリストを使用して、このようなとして返さ

_WA_Sys_00000014_004FB3FB ID 

使用して、実際の統計情報を取得する:

DBCC SHOW_STATISTICS('MyTable','_WA_Sys_00000002_004FB3FB') 

をこれのようなデータが返されます:

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 

All density Average Length Columns 
0.0006038647 4.459389 EffectiveDate 

と値のヒストグラムを示す別の行セットを。パフォーマンスの助けを求める

SELECT 'DBCC SHOW_STATISTICS([' + OBJECT_NAME(s.object_Id) + '],''' + s.Name + ''')' 
FROM sys.stats s 
    INNER JOIN sys.stats_columns sc 
    ON s.object_id = sc.object_id AND s.stats_id = sc.stats_id 
    INNER JOIN sys.columns c 
    ON sc.object_id = c.object_id AND sc.column_id = c.column_id 
WHERE s.Name LIKE '_WA%' 
ORDER BY s.stats_id, sc.column_id; 
+0

が役立ちますが、私は最終的には結果のtaテーブルcuzのすべての選択ステートメントを実行するカーソルが必要ですbleは私が必要とするものです – NFAL