SQL ServerからシステムヘルスXEからデータを取得し、後でクエリするためにテーブルにロードします。
かなり遅くなるそのステートメントの一部は
_INSERT INTO TABLE1
(
[object_name]
,[col1)
)
SELECT [Object_name], CAST (event_data as XML) AS eventcol1
FROM sys.fn_xe_file_target_read_file (N'D:\SQL\system_health*.XEL', NULL,NULL,NULL)
_
200kを超えるイベントをフェッチすると、上記は実際には遅い
テーブル構造は
_CREATE TABLE [dbo].[Table_1](
[object_name] [nvarchar](60) NOT NULL,
[col1] [xml] NULL
) ON [DEMO] TEXTIMAGE_ON [DEMO]
GO
_
テーブルの唯一のインデックスは_clustered index
_ on _object_name
_です[非一意]
Msdnから、column _event_data
_がnvarchar(max)
であることがわかりました
更新システムヘルスの42Kレコードでこの状況を再現できます。これは、7〜8秒実行され、0.5を超えると50分を超えます。システムヘルスからフェッチする100万レコード
リンク- PLan -これは、SQL2014以降のすべてのバージョンで、変換警告が表示されます。
SQL 2012では警告が表示されないため、トレースフラグ9481を使用しましたが、プロセスはまだ遅いです
提案してください
理由の一つを説明しようとしています。
現在object_name
はNon unique Clustered index
です。
したがって、データが挿入されると、database engine
は各ページで空のスペースを検索します。データはどこにでも格納できるため、このデータベースの検索には時間がかかります。
また、一意ではないため、オプティマイザーは各行に一意の識別子を追加して一意にします。このインデックスのコストは増加します。
したがって、挿入が遅くなるだけでなく、データを取得している間、インデックスのコストのためにインデックスは使用されません。
したがって、Ever Increasing Column
と同じようにSelective enough
、light data type
、Unique
およびClustered index
列を選択します
CREATE TABLE [dbo].[Table_1](
id int identity(1,1) primary key
[object_name] [nvarchar](60) NOT NULL,
[col1] [xml] NULL
) ON [DEMO] TEXTIMAGE_ON [DEMO]
GO
Non clustered index
にobject_name
を作成します。
ここで、database engine
は常にid int identity(1,1) primary key
であるため、データがページの最後に追加されることを認識します。したがって、挿入は高速になります。
チェックアウトする必要があります これは、拡張イベントXMLをより速くシュレッドする方法です 。
要旨は
また、マーティン・スミスによる以下の回答を参照してください