SQL Database は SQL Server プロファイラで接続をすることができないため、SQL Server で使用する機会の多い、プロファイラを用いたクエリのトレースを実施することができません。
データベースエンジンの SQL Server プロファイラを使用したトレースに関しては、今後廃止される予定の機能となっているため、SQL Database 向けに提供されることはないと思います。
SQL Database のクエリのトレース方法については、拡張イベントで実施するのが一般的な方法になるかと。
SQL Database の拡張イベントですが、データを永続化する場合は、ストレージに保存する形式となりますが、一時的なトレースであれば、リングバッファを使用することもできます。
デバッグ等でクエリを確認すればよいのであれば、リングバッファでもよいかなと思います。
リングバッファを使用したクエリのトレースは以下のようなコマンドで作成することができます。
-- クエリのトレース CREATE EVENT SESSION [QueryTrace] ON DATABASE ADD EVENT sqlserver.rpc_completed(SET collect_statement=(1) ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_hash_signed,sqlserver.query_plan_hash,sqlserver.query_plan_hash_signed,sqlserver.session_id,sqlserver.sql_text,sqlserver.username) WHERE ([statement]<>N'exec sp_reset_connection')), ADD EVENT sqlserver.sp_statement_completed( ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_hash_signed,sqlserver.query_plan_hash,sqlserver.query_plan_hash_signed,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)), ADD EVENT sqlserver.sql_batch_completed( ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_hash_signed,sqlserver.query_plan_hash,sqlserver.query_plan_hash_signed,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)), ADD EVENT sqlserver.sql_statement_completed( ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_name,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_hash_signed,sqlserver.query_plan_hash,sqlserver.query_plan_hash_signed,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)) ADD TARGET package0.ring_buffer WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=ON) GO ALTER EVENT SESSION [QueryTrace] ON DATABASE STATE = START GO
これで、クエリ系の情報を取得するための拡張イベントが作成され、1,000 件程度のイベントを取得することができるかと。
取得されたリングバッファのデータは以下のクエリでアクセスすることができます。
SELECT CAST(target_data AS XML) AS xml_data FROM sys.dm_xe_database_session_targets WHERE event_session_address = (SELECT address FROM sys.dm_xe_database_sessions WHERE name = 'QueryTrace')
取得できるデータは XML なので、クエリの情報を確認するためには少し加工したほうが良いかと。
単純に検索してしまうと、低いパフォーマンスレベルではかなり時間がかかってしまったため、以下のようなクエリで取得してみました。
DROP TABLE IF EXISTS #xmldata GO CREATE TABLE #xmldata (C1 int IDENTITY PRIMARY KEY, xml_data XML) INSERT INTO #xmldata (xml_data) SELECT CAST(target_data AS XML) AS xml_data FROM sys.dm_xe_database_session_targets WHERE event_session_address = (SELECT address FROM sys.dm_xe_database_sessions WHERE name = 'QueryTrace') CREATE PRIMARY XML INDEX idx_xml on #xmldata (xml_data) SELECT xed.event_data.value('(@timestamp)[1]','datetime2') AS timestamp, xed.event_data.value('(@name)[1]','varchar(255)') AS event_name, xed.event_data.value('(action[@name="sql_text"]/value)[1]','nvarchar(max)') AS sql_text, xed.event_data.value('(data[@name="statement"]/value)[1]','nvarchar(max)') AS statement, xed.event_data.value('(action[@name="username"]/value)[1]','nvarchar(255)') AS username, xed.event_data.value('(action[@name="client_hostname"]/value)[1]','nvarchar(255)') AS client_hostname, xed.event_data.value('(action[@name="client_app_name"]/value)[1]','nvarchar(max)') AS client_app_name FROM #xmldata CROSS APPLY xml_data.nodes('//RingBufferTarget/event') AS xed (event_data)
Basic で実行した場合、2~3 分程度実行に時間がかかると思いますが、以下のような実行結果を取得できます。
今回のクエリでは項目を絞っていますが、SQL Server プロファイラに近い情報はとれているかと。
もう一つの SQL Database のトレースとしては、「query_post_execution_showplan」になります。
-- クエリの進行状況取得用のトレース CREATE EVENT SESSION [QueryPlanTrace] ON DATABASE ADD EVENT sqlserver.query_post_execution_showplan ADD TARGET package0.ring_buffer WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF) GO ALTER EVENT SESSION [QueryPlanTrace] ON DATABASE STATE = START GO
SQL Database では、トレースフラグ 7412 が使用できないため、「SET STATISTICS XML ON」「SET STATISTICS PROFILE ON」を有効にするか、上記の拡張イベントを設定することにより、クエリの進行状況を取得することができます。
上記の拡張イベントを開始した後に実行されたクエリに関しては、クエリの進行状況を取得することができるようになりますので、デバッグや問題発生時に使用することができるかと。
SQL Database では、利用状況モニターが使用できないため、以下のようなクエリで進行状況を取得する必要があります。
SELECT qp.session_id, DB_NAME(qp.database_id) AS db_name, qp.request_id, ot.task_state, qp.physical_operator_name, qp.node_id, qp.thread_id, qp.row_count, qp.estimate_row_count, qp.elapsed_time_ms, qp.cpu_time_ms FROM sys.dm_exec_query_profiles qp CROSS APPLY sys.dm_exec_sql_text (sql_handle) t CROSS APPLY sys.dm_exec_query_plan(plan_handle) p LEFT JOIN sys.dm_os_tasks ot ON qp.task_address = ot.task_address WHERE qp.session_id <> @@SPID ORDER BY session_id, request_id, node_id, thread_id
実行結果としては以下のような情報が取得できます。
SQL Database の基本的なトレースとしては、上記の 2 種類が基本的なものになるのかなと。