Refresh-air

清风明月本无价 近水远山皆有情
记载自己在码砖过程中遇到的点点滴滴.......

 

sqlserver2005:T-Sql查询之物理查询优化

一、优化方法论

1.分析实例级的等待

2.联系等待和队列

3.确定方案

4.细化到数据库/文件级

5.细化到进程级

6.优化索引/查询

 

二、分析实例级的等待

在SQL SERVER 2005中,通过查询动态管理视图(DMV) sys.dm_os_wait_stats可以找出那些等待类型占用了大部分的等待时间,而在SQL SERVER 2000中,则通过运行DBCC SQLPERF(WAITSTATS)命令来完成。这个DMV从服务器最后一次重新启动开始累积值,若果你想重置它的值,运行下面的代码:DBCC SQLPERF('sys.dm_os_wait_stats',clear),在SQL SERVER 2000中下面的代码将重置等待统计:DBCC SQLPERF(waitstats,clear)。

重量级等待(Top Waits)

WITH Waits AS
(
  SELECT
    wait_type,
    wait_time_ms / 1000. AS wait_time_s,
    100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
    ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn
  FROM sys.dm_os_wait_stats
  WHERE wait_type NOT LIKE '%SLEEP%'
  -- filter out additional irrelevant waits
)
SELECT
  W1.wait_type, 
  CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
  CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
  CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
FROM Waits AS W1
  JOIN Waits AS W2
    ON W2.rn <= W1.rn
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING SUM(W2.pct) - W1.pct < 90 --v percentage threshold
ORDER BY W1.rn;
--  为了分析重量级等待,将等待信息记录下来
-- Create the WaitStats table
USE Performance;
GO
IF OBJECT_ID('dbo.WaitStats') IS NOT NULL
  DROP TABLE dbo.WaitStats;
GO

SELECT GETDATE() AS dt,
  wait_type, waiting_tasks_count, wait_time_ms,
  max_wait_time_ms, signal_wait_time_ms
INTO dbo.WaitStats
FROM sys.dm_os_wait_stats
WHERE 1 = 2;

ALTER TABLE dbo.WaitStats
  ADD CONSTRAINT PK_WaitStats PRIMARY KEY(dt, wait_type);
CREATE INDEX idx_type_dt ON dbo.WaitStats(wait_type, dt);
GO

-- Load waitstats data on regular intervals
INSERT INTO Performance.dbo.WaitStats
  SELECT GETDATE(),
    wait_type, waiting_tasks_count, wait_time_ms,
    max_wait_time_ms, signal_wait_time_ms
FROM sys.dm_os_wait_stats;
GO

-- Creation script for fn_interval_waits function
IF OBJECT_ID('dbo.fn_interval_waits') IS NOT NULL
  DROP FUNCTION dbo.fn_interval_waits;
GO

alter FUNCTION dbo.fn_interval_waits
  (@fromdt AS DATETIME, @todt AS DATETIME)
RETURNS TABLE
AS

RETURN
  WITH Waits AS
  (
    SELECT dt, wait_type, wait_time_ms,
      ROW_NUMBER() OVER(PARTITION BY wait_type
                        ORDER BY dt) AS rn
    FROM dbo.WaitStats
    WHERE dt >= '2010-07-10 23:24:46.783' 
      AND dt < '2010-07-12 23:24:46.783'  
  )
  SELECT Prv.wait_type, Prv.dt AS start_time,
    CAST((Cur.wait_time_ms - Prv.wait_time_ms)
           / 1000. AS DECIMAL(12, 2)) AS interval_wait_s
  FROM Waits AS Cur
    JOIN Waits AS Prv
      ON Cur.wait_type = Prv.wait_type
      AND Cur.rn = Prv.rn + 1
      AND Prv.dt <= '2010-07-13 23:24:46.783' ;
GO

-- Return interval waits
SELECT wait_type, start_time, interval_wait_s
FROM dbo.fn_interval_waits('20060212', '20060215') AS F
ORDER BY SUM(interval_wait_s) OVER(PARTITION BY wait_type) DESC,
  wait_type, start_time;
GO

-- Prepare view for pivot table
IF OBJECT_ID('dbo.VIntervalWaits') IS NOT NULL
  DROP VIEW dbo.VIntervalWaits;
GO

CREATE VIEW dbo.VIntervalWaits
AS

SELECT wait_type, start_time, interval_wait_s
FROM dbo.fn_interval_waits('2010-07-09 23:24:46.783', '2010-07-13 23:24:46.783') AS F;
三、联系等待和队列
-- SQL Server 2005
SELECT  object_name,  counter_name,  instance_name,  cntr_value,  cntr_type
FROM sys.dm_os_performance_counters;

-- SQL Server 2000
SELECT  object_name,  counter_name,  instance_name,  cntr_value,  cntr_type
FROM master.dbo.sysperfinfo;
GO
四、细化到数据库/文件级别
在数据库/文件级别分析I/O信息的工具是动态管理函数sys.dm_io_virtual_file_stats该函数接受一个数据库ID和文件ID作为输入,返回与该数据库文件相关的I/O信息,为
这两个参数指定NULL会返回所有数据库和所有文件的信息。
-- SQL Server 2005

-- Analyze DB IO
WITH DBIO AS
(
  SELECT
    DB_NAME(IVFS.database_id) AS db,
    CASE WHEN MF.type = 1 THEN 'log' ELSE 'data' END AS file_type,
    SUM(IVFS.num_of_bytes_read + IVFS.num_of_bytes_written) AS io,
    SUM(IVFS.io_stall) AS io_stall
  FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS IVFS
    JOIN sys.master_files AS MF
      ON IVFS.database_id = MF.database_id
      AND IVFS.file_id = MF.file_id
  GROUP BY DB_NAME(IVFS.database_id), MF.type
)
SELECT db, file_type, 
  CAST(1. * io / (1024 * 1024) AS DECIMAL(12, 2)) AS io_mb,
  CAST(io_stall / 1000. AS DECIMAL(12, 2)) AS io_stall_s,
  CAST(100. * io_stall / SUM(io_stall) OVER()
       AS DECIMAL(10, 2)) AS io_stall_pct,
  ROW_NUMBER() OVER(ORDER BY io_stall DESC) AS rn
FROM DBIO
ORDER BY io_stall DESC;

-- SQL Server 2000
SELECT * FROM ::fn_virtualfilestats(15, 1);
GO
五、细化到进程级别

posted on 2010-07-14 23:39  笑清风  阅读(457)  评论(0编辑  收藏  举报

导航