6

私のデータベースは古くなり、最大のINT IDENTITY列の 1 つは約 13 億の値を持っています。これで21億くらいオーバーフローします。サイズを大きくすることを計画していますが、データベース内のレコード数が多いため、あまり早くしたくありません。列のサイズを大きくする前に、データベース ハードウェアを交換すると、パフォーマンスの問題が相殺される可能性があります。また、50% を超えて使用されているデータベース内の他のすべての列にも注目したいと考えています。テーブルがたくさんあり、それぞれを手動でチェックするのは現実的ではありません。

これは私が現在値を取得する方法です (返される値が少し古くなっている可能性があることはわかっていますが、私の目的には十分です):

PRINT IDENT_CURRENT('MyDatabase.dbo.MyTable')

を使用しINFORMATION_SCHEMAてこの情報を取得できますか?

4

4 に答える 4

11

sys.identity_columnsシステム カタログ ビューを参照できます。

SELECT     
    name,
    seed_value, increment_value, last_value
FROM sys.identity_columns

これにより、各列の名前、シード、増分、および最後の値が得られます。ビューにはデータ型も含まれているため、すぐに番号が不足する可能性のある ID 列を簡単に把握できます...

于 2012-01-05T16:56:17.163 に答える
5

この問題を解決するストアド プロシージャを作成しました。を使用して列INFORMATION_SCHEMAを検索し、 および列を使用して使用率を計算します。データベースを最初のパラメーターとして指定し、オプションで最小パーセントとデータ型を指定します。IDENTITYIDENT_CURRENTDATA_TYPE

EXEC master.dbo.CheckIdentityColumns 'MyDatabase' --all

EXEC master.dbo.CheckIdentityColumns 'MyDatabase', 50 --columns 50% full or greater

EXEC master.dbo.CheckIdentityColumns 'MyDatabase', 50, 'int' --only int columns

出力例:

Table                     Column             Type    Percent Full Remaining
------------------------- ------------------ ------- ------------ ---------------
MyDatabase.dbo.Table1     Table1ID           int     9            1,937,868,393
MyDatabase.dbo.Table2     Table2ID           int     5            2,019,944,894
MyDatabase.dbo.Table3     Table3ID           int     9            1,943,793,775

すべてのデータベースを月に 1 回確認するようにリマインダーを作成し、この情報をスプレッドシートに記録しています。

IDENTITY 追跡スプレッドシート

CheckIdentityColumns プロシージャ

USE master
GO

CREATE PROCEDURE dbo.CheckIdentityColumns
    (
    @Database       AS NVARCHAR(128),
    @PercentFull    AS TINYINT          = 0,
    @Type           AS VARCHAR(8)       = NULL
    )

AS

--this procedure assumes you are not using negative numbers in your identity columns

DECLARE @Sql NVARCHAR(3000)

SET @Sql = 
'USE ' + @Database + '

SELECT                        
    [Column].TABLE_CATALOG + ''.'' +
    [Column].TABLE_SCHEMA + ''.'' +
    [Table].TABLE_NAME          AS [Table],
    [Column].COLUMN_NAME                        AS [Column],
    [Column].DATA_TYPE              AS [Type],
    CAST((
    CASE LOWER([Column].DATA_TYPE)
    WHEN ''tinyint''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 255)  
    WHEN ''smallint''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 32767)  
    WHEN ''int''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 2147483647)  
    WHEN ''bigint''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 9223372036854775807)  
    WHEN ''decimal''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / (([Column].NUMERIC_PRECISION * 10) - 1))  
    END * 100) AS INT)                  AS [Percent Full],
    REPLACE(CONVERT(VARCHAR(19), CAST(
    CASE LOWER([Column].DATA_TYPE)
    WHEN ''tinyint''
    THEN (255 - IDENT_CURRENT([Table].TABLE_NAME))  
    WHEN ''smallint''
    THEN (32767 - IDENT_CURRENT([Table].TABLE_NAME))  
    WHEN ''int''
    THEN (2147483647 - IDENT_CURRENT([Table].TABLE_NAME))  
    WHEN ''bigint''
    THEN (9223372036854775807 - IDENT_CURRENT([Table].TABLE_NAME))  
    WHEN ''decimal''
    THEN ((([Column].NUMERIC_PRECISION * 10) - 1) - IDENT_CURRENT([Table].TABLE_NAME))  
    END
    AS MONEY) , 1), ''.00'', '''')              AS Remaining


FROM                       
    INFORMATION_SCHEMA.COLUMNS                  AS [Column]

    INNER JOIN    
    INFORMATION_SCHEMA.TABLES                   AS [Table]
    ON      [Table].TABLE_NAME                  = [Column].TABLE_NAME

WHERE
    COLUMNPROPERTY(
        OBJECT_ID([Column].TABLE_NAME), 
        [Column].COLUMN_NAME, ''IsIdentity'') = 1 --true
    AND [Table].TABLE_TYPE                      = ''Base Table'' 
    AND [Table].TABLE_NAME                      NOT LIKE ''dt%'' 
    AND [Table].TABLE_NAME                      NOT LIKE ''MS%'' 
    AND [Table].TABLE_NAME                      NOT LIKE ''syncobj_%''
    AND CAST(
    (
    CASE LOWER([Column].DATA_TYPE)
    WHEN ''tinyint''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 255)  
    WHEN ''smallint''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 32767)  
    WHEN ''int''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 2147483647)  
    WHEN ''bigint''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / 9223372036854775807)  
    WHEN ''decimal''
    THEN (IDENT_CURRENT([Table].TABLE_NAME) / (([Column].NUMERIC_PRECISION * 10) - 1))  
    END * 100
    ) AS INT)                                    >= ' + CAST(@PercentFull AS VARCHAR(4))

IF (@Type IS NOT NULL) 
    SET @Sql = @Sql + 'AND  LOWER([Column].DATA_TYPE)    = ''' + LOWER(@Type) + ''''

SET @Sql = @Sql + '

ORDER BY
    [Column].TABLE_CATALOG + ''.'' +
    [Column].TABLE_SCHEMA + ''.'' +
    [Table].TABLE_NAME,
    [Column].COLUMN_NAME'

EXECUTE sp_executesql @Sql
GO
于 2012-01-05T16:12:53.523 に答える
2

Keith Walton には、非常に優れた非常に包括的なクエリがあります。ID 列がすべて整数であるという前提に基づいた、もう少し単純なものを次に示します。

SELECT sys.tables.name AS [Table Name], 
    last_value AS [Last Value],     
    MAX_LENGTH,
    CAST(cast(last_value as int) / 2147483647.0 * 100.0 AS DECIMAL(5,2)) 
        AS [Percentage of ID's Used], 
    2147483647 - cast(last_value as int) AS Remaining
FROM sys.identity_columns
    INNER JOIN sys.tables
        ON sys.identity_columns.object_id = sys.tables.object_id
ORDER BY last_value DESC

結果は次のようになります。

Table Name      Last Value      MAX_LENGTH  Percentage of ID's Used   Remaining
My_Table        49181800             4               2.29             2098301847

整数 ID 列のチェック

于 2013-04-15T15:49:58.860 に答える