sql >> データベース >  >> RDS >> Sqlserver

SQL Server再開可能インデックス:それはあなたにとって良いですか?

    SQL 2017では、データベースのメンテナンス中にインデックスの再構築操作を一時停止および再開する機能が導入されました。この機能により、データベース管理者は、必要に応じてインデックスの再構築を一時停止および再開するとともに、オフラインとオンラインのインデックスの再作成を選択できるため、柔軟性が向上します。

    再開可能なインデックスのリリース前に、データベース管理者はインデックスの再構築を実行できましたオフライン およびオンライン

    オフライン テーブルは読み取りに対してロックされているため、実行が高速になります。 または書き込み 操作し、新しいインデックスは古いインデックスから構築されます。このプロセス中、読み取りまたは書き込み操作は許可されません。操作が完了すると、テーブルロックが解除され、読み取りおよび書き込み操作が再度許可されます。 オフライン オプションは当然高速です。

    オンライン 読み取りのためにテーブルを開いたままにします および書き込み オペレーション。作成されたインデックスの別のコピーがあり、すべてのインデックス再構築操作はそのコピーにあります。すべての新しい行操作は、両方のインデックスに書き込まれます。再構築が完了すると、切り替えが行われ、新しいインデックスコピーが使用されます。 オンライン 再構築により、データベースがオンラインのときに再構築操作が可能になります。ダウンタイムは最小限です。

    再開可能なインデックス機能は、SQLServerEnterpriseエディションと無料のDeveloperエディションでのみ使用できることに注意してください。このオプションがテーブルにある場合は、それを試して簡単なテストを行い、この機能が自分のケースで役立つかどうかを確認できます。

    Microsoftのドキュメントには、考慮事項として次の側面が記載されています。

    • インデックスのメンテナンスウィンドウを管理、計画、および拡張できます。メンテナンスウィンドウに合わせる必要がある場合は、インデックスの作成または再構築の操作を一時停止して再開できます。
    • インデックスの作成または再構築の失敗(データベースのフェイルオーバーやディスク領域の不足など)から回復できます。
    • インデックス操作を一時停止すると、元のインデックスと新しく作成されたインデックスの両方にディスク容量が必要になることに注意してください。 DML操作中にそれらを更新する必要があります。
    • インデックスの作成または再構築操作中にトランザクションログの切り捨てを有効にできます。
    • SORT_IN_TEMPDB=ONオプションはサポートされていないことに注意してください

    再開可能なインデックスの再構築をテストしてみましょう。 SQL 2019 ServerDeveloperEditionを実行しているコンテナーイメージを使用します。また、数列の小さなテーブルを作成し、そのテーブルに約100万行を挿入します。行数を増やすと、テーブルを大きくすることができます。

    Linuxマシンを使用していて、SQL Server Management Studioをインストールできないため、AzureDataStudioクライアントを使用してSQLServerに接続します。私のSQLServerプロパティのスクリーンショットを見てください:

    以下のT-SQLスクリプトを使用して、サンプルデータベース、テーブル、およびインデックスを作成します。 SSMSまたはdbForgeStudioforSQLServerを使用して問題なく実行できます。

    -- Create a new database called 'DatabaseName' 
    -- Connect to the 'master' database to run this snippet 
    USE master 
    GO 
    -- Create the new database if it does not exist already 
    IF NOT EXISTS ( 
    SELECT [name] 
    FROM sys.databases 
    WHERE [name] = N'dbatools' 
    ) 
    CREATE DATABASE dbatools 
    GO
    Use dbatools 
    
    -- Create a new table called '[TableName]' in schema '[dbo]' 
    -- Drop the table if it already exists 
    IF OBJECT_ID('[dbo].[TabletoIndex]', 'U') IS NOT NULL 
    DROP TABLE [dbo].[TabletoIndex] 
    GO 
    -- Create the table in the specified schema 
    CREATE TABLE [dbo].[TabletoIndex] 
    ( 
    [Id] INT NOT NULL PRIMARY KEY, -- Primary Key column 
    [ColumnName1] NVARCHAR(50) NOT NULL 
    -- Specify more columns here 
    ); 
    GO 
    
    

    テーブルにランダムデータを入力するには、次のスクリプトを実行します。

    --populate the table 
    SET NOCOUNT ON 
    Declare @Id int 
    Set @Id = 1 
    While @Id <= 1000000 
    Begin 
    Insert Into TabletoIndex values (@Id, 'Name - ' + CAST(@Id as nvarchar(10))) Set @Id = @Id + 1 
    End 
    SELECT count(*) from TabletoIndex 
    

    入力されたテーブルの準備ができたら、再開可能なインデックスに進むことができます。そのインデックスの作成から始めましょう:

    -- Create a nonclustered index with or without a unique constraint -- Or create a clustered index on table '[TableName]' in schema '[dbo]' in database '[DatabaseName]' 
    CREATE UNIQUE INDEX IX_ID_Name ON [dbo].[TabletoIndex] (ID desc, [ColumnName1] DESC) WITH (SORT_IN_TEMPDB = OFF, RESUMABLE=ON, ONLINE = ON, MAX_DURATION=1) GO
    

    上記のコマンドの新しいオプション/パラメータに注意してください。 RESUMABLE =ON 再開可能なインデックス操作が必要であることを意味します。 Max_Duration インデックスを実行する時間を定義する値は分単位です。

    上記のコマンドの実行中に別のセッションを開き、以下のT-SQLコマンドを実行して一時停止します 進行中の再構築アクティビティ:

    --Rebuild WITH RESUMABLE functionality 
    ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] PAUSE 
    GO 
    

    一時停止の場合 コマンドが成功すると、約1分前に開始された現在のインデックス作成操作を一時停止します。ただし、 resumable =ON を使用して再構築コマンドの前のセッションに戻ると、 、醜いエラーを返します。うーん。しかし、はい、それは予想される動作です。

    この再開可能なインデックスの再構築に伴い、SQLServerは新しいDMV sys.index_resumable_operationsも導入しました。 一時停止した操作を確認します。このDMVを調べてみましょう:

    DMV結果クエリは、インデックス再構築コマンドを返します。完了率はすばらしいものです。すべてのインデックス再構築操作が完了すると、DMVは空を返します:

    かなりきちんとしていますね?

    しかし、テーブルについて気が変わったらどうしますか?要件に変更があり、データベース設計を変更する必要がある場合はどうなりますか?テーブルを削除してみましょう:

    別の醜い、長いエラーメッセージが表示されます:

    メッセージ10637、レベル16、状態1、行1
    1つ以上のインデックスが現在再開可能なインデックス再構築状態にあるため、ID581577110の「オブジェクト」に対してこの操作を実行できません。詳細については、sys.index_resumable_operationsを参照してください。
    合計実行時間:00:00:00.018

    ここから、操作を完全に中止するか、再開して再構築を完了する以外に選択肢がないことがわかります。

    操作を再開または中止するには、T-SQLコマンドを参照してください。その後、テーブルを正常に削除できます:

    ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] RESUME 
    ALTER INDEX IX_ID_Name ON [dbo].[TabletoIndex] ABORT 
    

    インデックスを完全に削除したり、現在のセッションを強制終了したりするなど、他の操作を行う必要がある場合にも、同じエラーが発生します。

    しかし、あなたは自問します、そもそも再開可能なオプションですか?答えはいいえだ。 SQL 2019の場合、すべてのインデックス作成はデフォルトでRESUMABLE=ONになります。これは、次の2つのスコープステートメントによるものです:

    ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_ONLINE=WHEN_SUPPORTED ALTER DATABASE SCOPED CONFIGURATION SET ELEVATE_RESUMABLE=WHEN_SUPPORTED 

    概要

    再開可能オプションを使用した場合のパフォーマンスへの影響は、通常のインデックス再作成操作を使用した場合と同じです。 SQL Serverを使用すると、データベースの保守操作をより細かく制御できます。

    周期表のインデックスの再構築の要件については、ビジネスへの影響を最小限に抑えるために、オフラインで、または少なくともオフピーク時にインデックス操作を実行することをお勧めします。


    1. パッケージのマルチレベルの依存関係を見つけるためのスクリプト

    2. MySQLでのREGEXP_INSTR()関数のしくみ

    3. MariaDBで英数字のみを含む行を返す2つの方法

    4. PostgreSQLクエリをログに記録する方法は?