偶發的儲存過程呼叫效能問題的一次調優過程
下面是在這種情況下的調優過程。[@more@]
1.
系統檢測
(1)取系統等待並且阻塞的程式
SET NOCOUNT ON
SET TRANSACTION ISOLATION
LEVEL READ UNCOMMITTED
GO
CREATE TABLE #block(
[current_time] [datetime] NOT NULL,
[resource_type] [nvarchar](60) NOT NULL,
[requested_object_name] [nvarchar](128) NULL,
[request_mode] [nvarchar](60) NOT NULL,
[request_status] [nvarchar](60) NOT NULL,
[resource_description] [nvarchar](2048) NULL,
[wait_duration_ms] [bigint] NULL,
[wait_type] [nvarchar](60) NULL,
[blocked_session_id] [smallint] NULL,
[blocked_start] [datetime] NOT NULL,
[blocked_command] [nvarchar](max) NULL,
[blocked_currentstat] [nvarchar](max) NULL,
[blocking_session_id] [smallint] NULL,
[blocking_start] [datetime] NULL,
[blocking_command] [nvarchar](max) NULL,
[blocking_currentstat] [nvarchar](max) NULL,
[blocking_wait_type] [nvarchar](60) NULL,
[blocking_wait_resource] [nvarchar](256) NULL,
[blocking_blocking] [smallint] NULL,
[blocking_wait_time] [int] NULL,
[open_transaction_count] [int] NULL,
[open_resultset_count] [int] NULL
)
GO
INSERT INTO #block
SELECT
GETDATE() AS [current_time]
,dtl.resource_type
,CASE
WHEN dtl.resource_type IN ('DATABASE', 'FILE', 'METADATA') THEN dtl.resource_type
WHEN dtl.resource_type = 'OBJECT' THEN OBJECT_NAME(dtl.resource_associated_entity_id)
WHEN dtl.resource_type IN ('KEY', 'PAGE', 'RID') THEN (
SELECT OBJECT_NAME([object_id])
FROM sys.partitions
WHERE sys.partitions.hobt_id = dtl.resource_associated_entity_id
)
ELSE 'Unidentified'
END AS requested_object_name
,dtl.request_mode
,dtl.request_status
,dowt.resource_description
,dowt.wait_duration_ms
,dowt.wait_type
,dowt.session_id AS
[blocked_session_id]
,sp_blocked.start_time AS
[blocked_start]
,desc_blocked.[text] AS
[blocked_command]
,SUBSTRING(desc_blocked.[text], sp_blocked.statement_start_offset /
2,
( CASE WHEN sp_blocked.statement_end_offset =
-1
THEN
LEN(CONVERT(NVARCHAR(MAX), desc_blocked.[text])) * 2
ELSE
sp_blocked.statement_end_offset
END - sp_blocked.statement_start_offset
) / 2) AS
[blocked_currentstat]
,dowt.blocking_session_id
,sp_blocking.start_time AS
[blocking_start]
,desc_blocking.[text] AS
[blocking_command]
,SUBSTRING(desc_blocking.[text], sp_blocking.statement_start_offset /
2,
( CASE WHEN sp_blocking.statement_end_offset =
-1
THEN
LEN(CONVERT(NVARCHAR(MAX),
desc_blocking.[text]))
* 2
ELSE
sp_blocking.statement_end_offset
END - sp_blocking.statement_start_offset
) / 2) AS
[blocking_currentstat]
,sp_blocking.wait_type [blocking_wait_type]
,sp_blocking.wait_resource AS
[blocking_wait_resource]
,sp_blocking.blocking_session_id AS
[blocking_blocking]
,sp_blocking.wait_time AS
[blocking_wait_time]
,sp_blocking.open_transaction_count
,sp_blocking.open_resultset_count
FROM sys.dm_tran_locks dtl
INNER JOIN sys.dm_os_waiting_tasks
dowt
ON dtl.lock_owner_address =
dowt.resource_address
INNER JOIN sys.dm_exec_requests
sp_blocked
ON dowt.[session_id] =
sp_blocked.session_id
LEFT JOIN sys.dm_exec_requests
sp_blocking
ON dowt.[blocking_session_id] =
sp_blocking.session_id
CROSS APPLY sys.[dm_exec_sql_text](sp_blocked.[sql_handle]) AS desc_blocked
OUTER APPLY sys.[dm_exec_sql_text](sp_blocking.[sql_handle]) AS desc_blocking
--WHERE
dtl.[resource_database_id] = DB_ID()
IF @@ROWCOUNT > 0
SELECT * FROM #block
WAITFOR DELAY '00:00:02'
GO 1000
(2)監控效能計數器,檢視是否有過長的佇列或日誌更新
Disk |
Displays |
Avg. Disk Queue Length |
|
Avg. Disk sec/Transfer |
|
SQLServer: Database object
counter |
|
Log Bytes Per Flush |
Number of bytes in the log
buffer when the buffer is flushed. |
Log Flushes/sec |
Number of log flushes per
second. |
Log Flush Wait Time |
Total wait time
(milliseconds) to flush the log. |
Log Flush Waits/sec |
Number of commits per second
that are waiting on log flush. |
(3)查是否有掛起的IO請求
select
db_name(i.database_id) as db,
m.name,
m.physical_name,
i.io_stall as [user_waittime_for_io(ms)],
p.io_type,
p.io_pending_ms_ticks as
[waittime_in_pending_queue]
from
sys.dm_io_virtual_file_stats(NULL, NULL) as i
inner
join sys.dm_io_pending_io_requests as p
on
i.file_handle = p.io_handle
inner
join sys.master_files as m
on m.database_id
= i.database_id
and
m.file_id = i.file_id
(4)檢視前15條呼叫最頻繁的儲存過程,或讀寫最多的儲存過程
SELECT TOP
15 a.object_id, a.database_id, OBJECT_NAME(object_id, database_id) 'proc name',
a.cached_time, a.last_execution_time, a.total_elapsed_time,
a.total_elapsed_time/a.execution_count AS
[avg_elapsed_time],
a.execution_count,
a.execution_count/(datediff(ss, sqlserver_start_time, last_execution_time) ) as execution_count_per_second,
a.total_physical_reads/a.execution_count avg_physical_reads,
a.total_logical_writes,
a.total_logical_writes/ a.execution_count avg_logical_reads,
a.last_elapsed_time,
a.total_elapsed_time / a.execution_count avg_elapsed_time,
b.text,c.query_plan
FROM sys.dm_exec_procedure_stats
AS a
CROSS APPLY
sys.dm_exec_sql_text(a.sql_handle) as b
CROSS APPLY
sys.dm_exec_query_plan(a.plan_handle) as c
cross join
sys.dm_os_sys_info as d
ORDER BY
[total_elapsed_time] DESC;
GO
2.
檢測結果
1)可以看到阻塞的源頭是WRITELOG;
(2)但windows的效能計數器磁碟佇列小於1,日誌更新的計數器也無特別異常;
(3)系統沒有掛起的IO請求;
(4)改儲存過程呼叫頻繁,每秒12次呼叫;用profiler可看到重複呼叫現象;
3.
調優方案
(1)報告應用端有重複呼叫現象;應用端修改重複呼叫;
(2)相關儲存過程可以使用nolock提示減低隔離級別;
(3)至此,效能應該有很大提高。但呼叫邏輯還可以進一步最佳化。如果效能再次成為問題的話,最佳化呼叫邏輯;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/66009/viewspace-1060731/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql多次呼叫儲存過程的問題MySql儲存過程
- Java呼叫Oracle儲存過程的問題JavaOracle儲存過程
- Hibernate呼叫oracle儲存過程的問題Oracle儲存過程
- 呼叫儲存過程儲存過程
- java儲存過程呼叫servlet的授權問題Java儲存過程Servlet
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- 儲存過程問題。。儲存過程
- 達夢儲存過程效能問題定位儲存過程
- 儲存過程呼叫其他模式的儲存過程需要注意的地方儲存過程模式
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- Winform呼叫儲存過程ORM儲存過程
- perl呼叫儲存過程儲存過程
- jdbc呼叫儲存過程JDBC儲存過程
- vb呼叫儲存過程的方法儲存過程
- Sqlsugar呼叫Oracle的儲存過程SqlSugarOracle儲存過程
- 一個儲存過程的問題!儲存過程
- 一次IO效能問題的發現過程
- JdbcTemplate調儲存過程JDBC儲存過程
- 一次效能優化調整過程.優化
- mysql如何呼叫儲存過程MySql儲存過程
- linux呼叫儲存過程Linux儲存過程
- PB中呼叫儲存過程儲存過程
- java 呼叫oracle 儲存過程JavaOracle儲存過程
- php呼叫mssql儲存過程PHPSQL儲存過程
- java中呼叫儲存過程Java儲存過程
- 用dbms_profiler調優儲存過程儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- 一次 kafka 消費者的效能調優過程Kafka
- 呼叫者儲存過程訪問許可權問題儲存過程訪問許可權
- job呼叫儲存過程的注意事項儲存過程
- 從sybase的儲存過程轉向oracle的儲存過程儲存過程Oracle
- MySQL儲存過程的許可權問題MySql儲存過程
- jsp中呼叫儲存過程JS儲存過程
- Spring mybatis 呼叫儲存過程SpringMyBatis儲存過程
- 用PHP呼叫MySQL儲存過程PHPMySql儲存過程
- c / c + + 呼叫mysql儲存過程MySql儲存過程
- C#呼叫 oracle儲存過程C#Oracle儲存過程
- C#呼叫Oracle儲存過程C#Oracle儲存過程