sqlserver的性能瓶颈

sqlserver的性能瓶颈,第1张

概述--sqlserver的性能瓶颈 --http://hi.baidu.com/cwh_blog/item/a85e86ddb46fbd57d73aae4f --http://msdn.microsoft.com/zh-cn/magazine/cc135978.aspx --许多应用程序效能的问题可能都是效能不佳的数据库查询语法造成的。我们该怎么样知道究竟瓶颈出现在哪里呢?基本上,SQL Serve

--sqlserver的性能瓶颈
--http://hi.baIDu.com/cwh_blog/item/a85e86ddb46fbd57d73aae4f
--http://msdn.microsoft.com/zh-cn/magazine/cc135978.aspx
--许多应用程序效能的问题可能都是效能不佳的数据库查询语法造成的。我们该怎么样知道究竟瓶颈出现在哪里呢?基本上,sql Server 2005会收集所执行的查询之相关数据,这些数据会保留在内存中,且在每次重新启动后开始累积,换句话说,重开机之后这些数据就会消失了。

--这些数据,包含了数据表索引、查询效能及服务器I/O相关的问题数据。我们可以透过sql Server Dynamic Management VIEws (DMV)和相关动态管理函数(Dynamic Management Functions,DMF)来查询这些数据,用来呈现服务器状态,利用来诊断问题及调整数据库效能。

--· 服务器等待的原因

SELECT top 10

[Wait type] = wait_type,

[Wait time (s)] = wait_time_ms / 1000,

[% waiting] = CONVERT(DECIMAL(12,2),wait_time_ms * 100.0

/ SUM(wait_time_ms) OVER())

FROM sys.dm_os_wait_stats

WHERE wait_type NOT liKE '%sLEEP%'

ORDER BY wait_time_ms DESC;

--· 读取及写入

SELECT top 10

[Total Reads] = SUM(total_logical_reads)

,[Execution count] = SUM(qs.execution_count)

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

GROUP BY DB_name(qt.dbID)

ORDER BY [Total Reads] DESC;

SELECT top 10

[Total Writes] = SUM(total_logical_writes)

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

GROUP BY DB_name(qt.dbID)

ORDER BY [Total Writes] DESC;

--· 遗漏数据库索引

SELECT

Databasename = DB_name(database_ID)

,[Number Indexes Missing] = count(*)

FROM sys.dm_db_missing_index_details

GROUP BY DB_name(database_ID)

ORDER BY 2 DESC;

--· 高成本的遗漏索引

SELECT top 10

[Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0)

,avg_user_impact

,tablename = statement

,[EqualityUsage] = equality_columns

,[InequalityUsage] = inequality_columns

,[Include Cloumns] = included_columns

FROM sys.dm_db_missing_index_groups g

INNER JOIN sys.dm_db_missing_index_group_stats s

ON s.group_handle = g.index_group_handle

INNER JOIN sys.dm_db_missing_index_details d

ON d.index_handle = g.index_handle

ORDER BY [Total Cost] DESC;

--· 未使用的索引

-- Create required table structure only.

-- Note: this sql must be the same as in the Database loop given in the following step.

SELECT top 1

Databasename = DB_name()

,tablename = OBJECT_name(s.[object_ID])

,Indexname = i.name

,user_updates

,system_updates

-- Useful fIElds below:

--,*

INTO #Tempunusedindexes

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.database_ID = DB_ID()

AND OBJECTPROPERTY(s.[object_ID],'IsMsShipped') = 0

AND user_seeks = 0

AND user_scans = 0

AND user_lookups = 0

AND s.[object_ID] = -999 -- Dummy value to get table structure.

;

-- Loop around all the databases on the server.

EXEC sp_MSForEachDB 'USE [?];

-- table already exists.

INSERT INTO #Tempunusedindexes

SELECT top 10

Databasename = DB_name()

,system_updates

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.database_ID = DB_ID()

AND OBJECTPROPERTY(s.[object_ID],''IsMsShipped'') = 0

AND user_seeks = 0

AND user_scans = 0

AND user_lookups = 0

AND i.name IS NOT NulL -- Ignore HEAP indexes.

ORDER BY user_updates DESC

;

'

-- Select records.

SELECT top 10 * FROM #Tempunusedindexes ORDER BY [user_updates] DESC

-- TIDy up.

DROP table #Tempunusedindexes

--· 高成本的使用中索引

-- Create required table structure only.

-- Note: this sql must be the same as in the Database loop given in the following step.

SELECT top 1

[Maintenance cost] = (user_updates + system_updates)

,[RetrIEval usage] = (user_seeks + user_scans + user_lookups)

,Databasename = DB_name()

,Indexname = i.name

INTO #TempMaintenanceCost

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.database_ID = DB_ID()

AND OBJECTPROPERTY(s.[object_ID],'IsMsShipped') = 0

AND (user_updates + system_updates) > 0 -- Only report on active rows.

AND s.[object_ID] = -999 -- Dummy value to get table structure.

;

-- Loop around all the databases on the server.

EXEC sp_MSForEachDB 'USE [?];

-- table already exists.

INSERT INTO #TempMaintenanceCost

SELECT top 10

[Maintenance cost] = (user_updates + system_updates)

,Indexname = i.name

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.database_ID = DB_ID()

AND i.name IS NOT NulL -- Ignore HEAP indexes.

AND OBJECTPROPERTY(s.[object_ID],''IsMsShipped'') = 0

AND (user_updates + system_updates) > 0 -- Only report on active rows.

ORDER BY [Maintenance cost] DESC

;

'

-- Select records.

SELECT top 10 * FROM #TempMaintenanceCost

ORDER BY [Maintenance cost] DESC

-- TIDy up.

DROP table #TempMaintenanceCost

--· 常用的索引

-- Create required table structure only.

-- Note: this sql must be the same as in the Database loop given in the -- following step.

SELECT top 1

[Usage] = (user_seeks + user_scans + user_lookups)

,Indexname = i.name

INTO #Tempusage

FROM sys.dm_db_index_usage_stats s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.database_ID = DB_ID()

AND OBJECTPROPERTY(s.[object_ID],'IsMsShipped') = 0

AND (user_seeks + user_scans + user_lookups) > 0

-- Only report on active rows.

AND s.[object_ID] = -999 -- Dummy value to get table structure.

;

-- Loop around all the databases on the server.

EXEC sp_MSForEachDB 'USE [?];

-- table already exists.

INSERT INTO #Tempusage

SELECT top 10

[Usage] = (user_seeks + user_scans + user_lookups)

,''IsMsShipped'') = 0

AND (user_seeks + user_scans + user_lookups) > 0 -- Only report on active rows.

ORDER BY [Usage] DESC

;

'

-- Select records.

SELECT top 10 * FROM #Tempusage ORDER BY [Usage] DESC

-- TIDy up.

DROP table #Tempusage

--· 逻辑片段的索引

-- Create required table structure only.

-- Note: this sql must be the same as in the Database loop given in the -- following step.

SELECT top 1

Datbasename = DB_name()

,[Fragmentation %] = ROUND(avg_fragmentation_in_percent,2)

INTO #TempFragmentation

FROM sys.dm_db_index_physical_stats(db_ID(),null,null) s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.[object_ID] = -999 -- Dummy value just to get table structure.

;

-- Loop around all the databases on the server.

EXEC sp_MSForEachDB 'USE [?];

-- table already exists.

INSERT INTO #TempFragmentation

SELECT top 10

Datbasename = DB_name()

,2)

FROM sys.dm_db_index_physical_stats(db_ID(),null) s

INNER JOIN sys.indexes i ON s.[object_ID] = i.[object_ID]

AND s.index_ID = i.index_ID

WHERE s.database_ID = DB_ID()

AND i.name IS NOT NulL -- Ignore HEAP indexes.

AND OBJECTPROPERTY(s.[object_ID],''IsMsShipped'') = 0

ORDER BY [Fragmentation %] DESC

;

'

-- Select records.

SELECT top 10 * FROM #TempFragmentation ORDER BY [Fragmentation %] DESC

-- TIDy up.

DROP table #TempFragmentation

--· I/O的高成本查询

SELECT top 10

[Average IO] = (total_logical_reads + total_logical_writes) / qs.execution_count

,[Total IO] = (total_logical_reads + total_logical_writes)

,[Execution count] = qs.execution_count

,[IndivIDual query] = SUBSTRING (qt.text,qs.statement_start_offset/2,

(CASE WHEN qs.statement_end_offset = -1

THEN LEN(CONVERT(NVARCHAR(MAX),qt.text)) * 2

ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)

,[Parent query] = qt.text

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

ORDER BY [Average IO] DESC;

--· cpu的高成本查询

SELECT top 10

[Average cpu used] = total_worker_time / qs.execution_count

,[Total cpu used] = total_worker_time

,qt.text)) * 2

ELSE qs.statement_end_offset END -

qs.statement_start_offset)/2)

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

ORDER BY [Average cpu used] DESC;

--· 高成本的CLR查询

SELECT top 10

[Average CLR Time] = total_clr_time / execution_count

,[Total CLR Time] = total_clr_time

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats as qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

WHERE total_clr_time <> 0

ORDER BY [Average CLR Time] DESC;

--· 最常执行的查询

SELECT top 10

[Execution count] = execution_count

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

ORDER BY [Execution count] DESC;

--· 遭到封锁的查询

SELECT top 10

[Average Time Blocked] = (total_elapsed_time - total_worker_time) / qs.execution_count

,[Total Time Blocked] = total_elapsed_time - total_worker_time

,Databasename = DB_name(qt.dbID)

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt

ORDER BY [Average Time Blocked] DESC;

--最低计划重复使用率

SELECT top 10

[Plan usage] = cp.usecounts

,

qt.text)) * 2 ELSE qs.statement_end_offset END -

qs.statement_start_offset)/2)

,Databasename = DB_name(qt.dbID)

,cp.cacheobjtype

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt

INNER JOIN sys.dm_exec_cached_plans as cp on qs.plan_handle=cp.plan_handle

WHERE cp.plan_handle=qs.plan_handle

ORDER BY [Plan usage] ASC;

总结

以上是内存溢出为你收集整理的sqlserver的性能瓶颈全部内容,希望文章能够帮你解决sqlserver的性能瓶颈所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1177762.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存