Sql-Server-2017
這個查詢來自哪裡?
我在 SQL 2017 上啟用了查詢儲存,並且我看到在
SELECT *
特定表上經常發生的查詢。我想縮小這個請求的來源,看看我們是否能找到比
SELECT *
.當然,我有一個來自 Query Store 的查詢 ID。我最近還要求我的開發人員在他們的連接字元串中包含應用程序名稱,許多人都這樣做了。
有沒有辦法(例如,可能使用 DMV)可以找到與此查詢關聯的應用程序名稱?
查詢查詢儲存 DMV 以獲取查詢雜湊,然後在擴展事件會話中使用該查詢雜湊來擷取相關詳細資訊。
這應該可以幫助您:
SELECT qsq.query_hash , qsqt.query_sql_text FROM sys.query_store_query qsq INNER JOIN sys.query_store_query_text qsqt ON qsq.query_text_id = qsqt.query_text_id WHERE qsqt.query_sql_text LIKE '%some-pertinent-SQL%';
在上面的查詢中,我有
LIKE '%some-pertinent-SQL%'
- 這限制了查詢的結果以匹配您正在尋找的目標 - 您需要將 替換some-pertinent-SQL
為您的目標查詢的唯一部分。
query_hash
在擴展事件會話定義中使用上面返回的列中的值:CREATE EVENT SESSION [t] ON SERVER ADD EVENT sqlserver.sql_statement_completed( ACTION(sqlserver.client_app_name , sqlserver.client_hostname , sqlserver.nt_username , sqlserver.plan_handle , sqlserver.query_hash) WHERE ([sqlserver].[query_hash]=(0x00000000)) ) ADD TARGET package0.ring_buffer WITH (STARTUP_STATE=OFF); GO
將 替換
0x00000000
為實際的查詢雜湊值。使用以下命令啟動擴展事件會話:
ALTER EVENT SESSION [t] ON SERVER STATE = START;
右鍵點擊對象資源管理器中的擴展事件會話以查看有關客戶端主機名、使用者名等的詳細資訊,以便在查詢發生時進行查詢。
為了測試這一點,我在我的 SQL Server 2016 測試實例上執行了以下程式碼:
CREATE DATABASE QueryStoreTest ON PRIMARY ( NAME = QueryStoreTest_primary , FILENAME = 'C:\temp\QueryStoreTest_primary.mdf' , SIZE = 100MB , FILEGROWTH = 100MB , MAXSIZE = 1000MB ) LOG ON ( NAME = QueryStoreTest_log , FILENAME = 'C:\temp\QueryStoreTest_log.ldf' , SIZE = 100MB , FILEGROWTH = 100MB , MAXSIZE = 1000MB ); GO ALTER DATABASE QueryStoreTest SET QUERY_STORE = ON;
在這裡,我將在 QueryStoreTest 數據庫中創建幾個對象和一個測試查詢:
USE QueryStoreTest; CREATE TABLE dbo.qst ( id int NOT NULL PRIMARY KEY CLUSTERED IDENTITY(1,1) ); CREATE TABLE dbo.qst2 ( id int NOT NULL PRIMARY KEY CLUSTERED IDENTITY(1,1) ); SELECT * /* test query store query */ FROM dbo.qst LEFT MERGE JOIN dbo.qst2 on qst.id = qst2.id;
在這裡,我將從查詢儲存中獲取查詢雜湊:
SELECT qsq.query_hash , qsqt.query_sql_text FROM sys.query_store_query qsq INNER JOIN sys.query_store_query_text qsqt ON qsq.query_text_id = qsqt.query_text_id WHERE qsqt.query_sql_text LIKE '%test query store query%';
結果:
╔════════════════════╦════════════════════════════════════════════════════════╗ ║ query_hash ║ query_sql_text ║ ╠════════════════════╬════════════════════════════════════════════════════════╣ ║ 0x3A0100223AD74766 ║ SELECT * /* 測試查詢儲存查詢 */ FROM dbo.qst ║ ║ ║ 左合併加入 dbo.qst2 on qst.id = qst2.id ║ ╚════════════════════╩════════════════════════════════════════════════════════╝
現在,我將創建擴展事件會話:
CREATE EVENT SESSION [t] ON SERVER ADD EVENT sqlserver.sql_statement_completed ( ACTION ( sqlserver.client_app_name , sqlserver.client_hostname , sqlserver.nt_username , sqlserver.plan_handle , sqlserver.query_hash ) WHERE ([sqlserver].[query_hash]=(0x3A0100223AD74766)) ) ADD TARGET package0.ring_buffer WITH (STARTUP_STATE=OFF) GO
並開始會話:
ALTER EVENT SESSION [t] ON SERVER STATE = START;
現在,如果我執行測試查詢並查看會話中的實時數據,我會看到:
清理:
USE master; GO ALTER EVENT SESSION [t] ON SERVER STATE = STOP; GO DROP EVENT SESSION [t] ON SERVER; GO ALTER DATABASE QueryStoreTest SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE QueryStoreTest;