1. 程式人生 > >SQL SERVER效能優化SQL

SQL SERVER效能優化SQL


sql server 效能優化方法


--檢視是否有死鎖
dECLARE  @tab TABLE(NAME varchar(100),value varchar(200));
INSERT INTO @tab EXEC('DBCC OPENTRAN WITH TABLERESULTS');
SELECT name,CAST(value AS DATETIME) startDate,getdate() currentDate
,DATEDIFF(s,CAST(value AS DATETIME),getdate()) diffsecond FROM @tab WHERE name in 
('OLDACT_STARTTIME')
 SELECT   spid,
         blocked,
         DB_NAME(sp.dbid) AS DBName,
         program_name,
         waitresource,
         lastwaittype,
         sp.loginame,
         sp.hostname,
         a.[Text] AS [TextData],
         SUBSTRING(A.text, sp.stmt_start / 2, 
         (CASE WHEN sp.stmt_end = -1 THEN DATALENGTH(A.text) ELSE sp.stmt_end 
         END - sp.stmt_start) / 2) AS [current_cmd]
FROM     sys.sysprocesses AS sp OUTER APPLY sys.dm_exec_sql_text (sp.sql_handle) AS A
WHERE  spid =(SELECT CASE WHEN ISNUMERIC(value)=0 THEN -1 ELSE value end FROM @tab WHERE name in 
('OLDACT_SPID') )


 
--檢視當前正在執行的sql語句
SELECT  [Spid] = session_id , ecid ,
            [Database] = DB_NAME(sp.dbid) ,[User] = nt_username ,
            [Status] = er.status , [Wait] = wait_type ,
            [Individual Query] = SUBSTRING(qt.text,
                                           er.statement_start_offset / 2,
                                           ( CASE WHEN er.statement_end_offset = -1
                                                  THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))
                                                       * 2
                                                  ELSE er.statement_end_offset
                                             END - er.statement_start_offset )
                                           / 2) ,
            [Parent Query] = qt.text , Program = program_name ,hostname ,  nt_domain , start_time
    FROM    sys.dm_exec_requests er
            INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
            CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
    WHERE   session_id > 50 -- Ignore system spids.
            AND session_id NOT IN ( @@SPID ) -- Ignore this current statement.
ORDER BY    1 ,
            2 

--刪除解鎖
KILL 1000  --spid

 

查詢前 10 個可能是效能最差的 SQL 語句

SELECT TOP 10 TEXT AS 'SQL Statement'
    ,last_execution_time AS 'Last Execution Time'
    ,(total_logical_reads + total_physical_reads + total_logical_writes) / execution_count AS [Average IO]
    ,(total_worker_time / execution_count) / 1000000.0 AS [Average CPU Time (sec)]
    ,(total_elapsed_time / execution_count) / 1000000.0 AS [Average Elapsed Time (sec)]
    ,execution_count AS "Execution Count"
    ,qp.query_plan AS "Query Plan"
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY total_elapsed_time / execution_count DESC


查詢邏輯讀取最高的sql
SELECT TOP ( 25 )
        P.name AS [SP Name] ,
        Deps.total_logical_reads AS [TotalLogicalReads] ,
        deps.total_logical_reads / deps.execution_count AS [AvgLogicalReads] ,
        deps.execution_count ,
        ISNULL(deps.execution_count / DATEDIFF(SECOND, deps.cached_time,
                                               GETDATE()), 0) AS [Calls/Second] ,
        deps.total_elapsed_time ,
        deps.total_elapsed_time / deps.execution_count AS [avg_elapsed_time] ,
        deps.cached_time
FROM    sys.procedures AS p
        INNER JOIN sys.dm_exec_procedure_stats AS deps ON p.[Object_id] = deps.[Object_id]
WHERE   deps.Database_id = DB_ID()
ORDER BY deps.total_logical_reads DESC

 查詢索引碎片
--建立變數 指定要檢視的表
declare @table_id int
set @table_id=object_id('TableName')
--執行
dbcc showcontig(@table_id)

Logical Scan Fragmentation-邏輯掃描碎片:該百分比應該在0%到10%之間,高了則說明有外部碎片。 
Extent Scan Fragmentation-擴充套件盤區掃描碎片:該百分比應該是0%,高了則說明有外部碎片。 
掃描密度[最佳值:實際值]:該百分比應該儘可能靠近100%。低了則說明有外部碎片。

查詢未使用過的索引
SELECT 'SQL Server Instance Start with ' + CONVERT(VARCHAR(16),create_date,120)  FROM sys.databases
WHERE database_id =2;
    
SELECT  DB_NAME(diu.database_id)                  AS DatabaseName ,
        s.name +'.' +QUOTENAME(o.name)            AS TableName    ,
        i.index_id                                AS IndexID   ,
        i.name                                    AS IndexName        ,
        CASE WHEN i.is_unique =1 THEN 'UNIQUE INDEX'
           ELSE 'NOT UNIQUE INDEX'    END         AS IS_UNIQUE,
        CASE WHEN i.is_disabled=1 THEN 'DISABLE'
           ELSE 'ENABLE'            END           AS IndexStatus,
        o.create_date                             AS IndexCreated,
        STATS_DATE(o.object_id,i.index_id)        AS StatisticsUpdateDate,
        diu.user_seeks                            AS UserSeek ,
        diu.user_scans                            AS UserScans ,
        diu.user_lookups                          AS UserLookups ,
        diu.user_updates                          AS UserUpdates ,
        p.TableRows ,
        'DROP INDEX ' + QUOTENAME(i.name) 
        + ' ON ' + QUOTENAME(s.name) + '.'
        + QUOTENAME(OBJECT_NAME(diu.object_id)) +';' AS 'Drop Index Statement'
FROM    sys.dm_db_index_usage_stats diu
        INNER JOIN sys.indexes i ON i.index_id = diu.index_id
                                    AND diu.object_id = i.object_id
        INNER JOIN sys.objects o ON diu.object_id = o.object_id
        INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
        INNER JOIN ( SELECT SUM(p.rows) TableRows ,
                            p.index_id ,
                            p.object_id
                     FROM   sys.partitions p
                     GROUP BY p.index_id ,
                            p.object_id
                   ) p ON p.index_id = diu.index_id
                          AND diu.object_id = p.object_id
WHERE   OBJECTPROPERTY(diu.object_id, 'IsUserTable') = 1
        AND diu.database_id = DB_ID()
        AND i.is_primary_key = 0        --排除主鍵索引
        AND i.is_unique_constraint = 0         --排除唯一索引
        AND diu.user_updates <> 0              --排除沒有資料變化的索引
        AND diu.user_lookups = 0
        AND diu.user_seeks = 0
        AND diu.user_scans = 0
        AND i.name IS NOT NULL                 --排除那些沒有任何索引的堆表
ORDER BY ( diu.user_seeks + diu.user_scans + diu.user_lookups ) ASC,diu.user_updates DESC;
GO