首页 > 数据库技术 > 详细

SQL SERVER性能优化SQL

时间:2020-02-29 14:25:18      阅读:103      评论:0      收藏:0      [点我收藏+]
原文:SQL SERVER性能优化SQL

 

                                         sql server 性能优化方法

 

目录

                        

一、查看是否有死锁

二、查看当前正在执行的sql语句

三、查询前 10 个可能是性能最差的 SQL 语句

四、查询逻辑读取最高的sql

五、 查询索引碎片

六、修改索引填充因子(FILLFACTOR:填充因子,ONLINE:ON 重建索引时表仍然可以正常使用)

七、查询未使用过的索引

八、查询表下索引使用情况

         九、查询表结构信息



一、查看是否有死锁

  1. dECLARE  @tab TABLE(NAME varchar(100),value varchar(200));
  2. INSERT INTO @tab EXEC(‘DBCC OPENTRAN WITH TABLERESULTS‘);
  3. SELECT name,CAST(value AS DATETIME) startDate,getdate() currentDate
  4. ,DATEDIFF(s,CAST(value AS DATETIME),getdate()) diffsecond FROM @tab WHERE name in 
  5. (‘OLDACT_STARTTIME‘)
  6.  SELECT   spid,
  7.          blocked,
  8.          DB_NAME(sp.dbid) AS DBName,
  9.          program_name,
  10.          waitresource,
  11.          lastwaittype,
  12.          sp.loginame,
  13.          sp.hostname,
  14.          a.[Text] AS [TextData],
  15.          SUBSTRING(A.text, sp.stmt_start / 2
  16.          (CASE WHEN sp.stmt_end = -1 THEN DATALENGTH(A.text) ELSE sp.stmt_end 
  17.          END - sp.stmt_start) / 2) AS [current_cmd]
  18. FROM     sys.sysprocesses AS sp OUTER APPLY sys.dm_exec_sql_text (sp.sql_handle) AS A
  19. WHERE  spid =(SELECT CASE WHEN ISNUMERIC(value)=0 THEN -1 ELSE value end FROM @tab WHERE name in 
  20. (‘OLDACT_SPID‘) )

 

二、查看当前正在执行的sql语句

  1. SELECT  [Spid] = session_id , ecid ,
  2.             [Database] = DB_NAME(sp.dbid) ,[User] = nt_username ,
  3.             [Status] = er.status , [Wait] = wait_type ,
  4.             [Individual Query] = SUBSTRING(qt.text,
  5.                                            er.statement_start_offset / 2,
  6.                                            ( CASE WHEN er.statement_end_offset = -1
  7.                                                   THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))
  8.                                                        * 2
  9.                                                   ELSE er.statement_end_offset
  10.                                              END - er.statement_start_offset )
  11.                                            / 2) ,
  12.             [Parent Query] = qt.text , Program = program_name ,hostname ,  nt_domain , start_time
  13.     FROM    sys.dm_exec_requests er
  14.             INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
  15.             CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
  16.     WHERE   session_id > 50 -- Ignore system spids.
  17.             AND session_id NOT IN ( @@SPID ) -- Ignore this current statement.
  18. ORDER BY    1 ,
  19.             2 
  20. --删除解锁
  21. KILL 1000  --spid

 

三、查询前 10 个可能是性能最差的 SQL 语句

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

 

四、查询逻辑读取最高的sql

  1. SELECT TOP ( 25 )
  2.         P.name AS [SP Name] ,
  3.         Deps.total_logical_reads AS [TotalLogicalReads] ,
  4.         deps.total_logical_reads / deps.execution_count AS [AvgLogicalReads] ,
  5.         deps.execution_count ,
  6.         ISNULL(deps.execution_count / DATEDIFF(SECOND, deps.cached_time,
  7.                                                GETDATE()), 0) AS [Calls/Second] ,
  8.         deps.total_elapsed_time ,
  9.         deps.total_elapsed_time / deps.execution_count AS [avg_elapsed_time] ,
  10.         deps.cached_time
  11. FROM    sys.procedures AS p
  12.         INNER JOIN sys.dm_exec_procedure_stats AS deps ON p.[Object_id] = deps.[Object_id]
  13. WHERE   deps.Database_id = DB_ID()
  14. ORDER BY deps.total_logical_reads DESC

五、 查询索引碎片

  1. --创建变量 指定要查看的表
  2. declare @table_id int
  3. set @table_id=object_id(‘TableName‘)
  4. --执行
  5. dbcc showcontig(@table_id)

Logical Scan Fragmentation-逻辑扫描碎片:该百分比应该在0%到10%之间,高了则说明有外部碎片。 

Extent Scan Fragmentation-扩展盘区扫描碎片:该百分比应该是0%,高了则说明有外部碎片。 

扫描密度[最佳值:实际值]:该百分比应该尽可能靠近100%。低了则说明有外部碎片。

六、修改索引填充因子(FILLFACTOR:填充因子,ONLINE:ON 重建索引时表仍然可以正常使用)

  1. --修改表下所有索引填充因子 
  2. ALTER INDEX ALL ON TableName REBUILD WITH (FILLFACTOR=90,ONLINE=ON)
  3. --修改表下指定索引填充因子
  4. ALTER INDEX indexName ON  TableName REBUILD WITH (FILLFACTOR = 80);   

 

七、查询未使用过的索引

 

  1. SELECT  DB_NAME(diu.database_id)                  AS DatabaseName ,
  2.         s.name +‘.‘ +QUOTENAME(o.name)            AS TableName    ,
  3.         i.index_id                                AS IndexID   ,
  4.         i.name                                    AS IndexName        ,
  5.         CASE WHEN i.is_unique =1 THEN ‘UNIQUE INDEX‘
  6.            ELSE ‘NOT UNIQUE INDEX‘    END         AS IS_UNIQUE,
  7.         CASE WHEN i.is_disabled=1 THEN ‘DISABLE‘
  8.            ELSE ‘ENABLE‘            END           AS IndexStatus,
  9.         o.create_date                             AS IndexCreated,
  10.         STATS_DATE(o.object_id,i.index_id)        AS StatisticsUpdateDate,
  11.         diu.user_seeks                            AS UserSeek ,
  12.         diu.user_scans                            AS UserScans ,
  13.         diu.user_lookups                          AS UserLookups ,
  14.         diu.user_updates                          AS UserUpdates ,
  15.         p.TableRows ,
  16.         ‘DROP INDEX ‘ + QUOTENAME(i.name) 
  17.         + ‘ ON ‘ + QUOTENAME(s.name) + ‘.‘
  18.         + QUOTENAME(OBJECT_NAME(diu.object_id)) +‘;‘ AS ‘Drop Index Statement‘
  19. FROM    sys.dm_db_index_usage_stats diu
  20.         INNER JOIN sys.indexes i ON i.index_id = diu.index_id
  21.                                     AND diu.object_id = i.object_id
  22.         INNER JOIN sys.objects o ON diu.object_id = o.object_id
  23.         INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
  24.         INNER JOIN ( SELECT SUM(p.rows) TableRows ,
  25.                             p.index_id ,
  26.                             p.object_id
  27.                      FROM   sys.partitions p
  28.                      GROUP BY p.index_id ,
  29.                             p.object_id
  30.                    ) p ON p.index_id = diu.index_id
  31.                           AND diu.object_id = p.object_id
  32. WHERE   OBJECTPROPERTY(diu.object_id, ‘IsUserTable‘) = 1
  33.         AND diu.database_id = DB_ID()
  34.         AND i.is_primary_key = 0        --排除主键索引
  35.         AND i.is_unique_constraint = 0         --排除唯一索引
  36.         AND diu.user_updates <> 0              --排除没有数据变化的索引
  37.         AND diu.user_lookups = 0
  38.         AND diu.user_seeks = 0
  39.         AND diu.user_scans = 0
  40.         AND i.name IS NOT NULL                 --排除那些没有任何索引的堆表
  41. ORDER BY ( diu.user_seeks + diu.user_scans + diu.user_lookups ) ASC,diu.user_updates DESC;
  42. GO

 

八、查询表下索引使用情况

  1.  select db_name(database_id) as N‘数据库名称‘,
  2.        object_name(a.object_id) as N‘表名‘,
  3.        b.name N‘索引名称‘,
  4.        user_seeks N‘用户索引查找次数‘,
  5.        user_scans N‘用户索引扫描次数‘,
  6.        max(last_user_seek) N‘最后查找时间‘,
  7.        max(last_user_scan) N‘最后扫描时间‘,
  8.        max(rows) as N‘表中的行数‘
  9. from sys.dm_db_index_usage_stats a join 
  10.      sys.indexes b
  11.      on a.index_id = b.index_id
  12.      and a.object_id = b.object_id
  13.      join sysindexes c
  14.      on c.id = b.object_id
  15. where database_id=db_id(‘数据库名称‘)   --指定数据库
  16.      and object_name(a.object_id) not like ‘sys%‘
  17.      and object_name(a.object_id) like ‘表名‘  --指定索引表
  18.      and b.name is not null
  19.      --and b.name like ‘索引名‘ --指定索引名称 可以先使用 sp_help ‘你的表名‘ 查看表的结构和所有的索引信息
  20. group by db_name(database_id) ,
  21.        object_name(a.object_id),
  22.        b.name,
  23.        user_seeks ,
  24.        user_scans 
  25. order by user_seeks,user_scans,object_name(a.object_id)

 九、查询表结构信息

  1. SELECT 表名 = CASE WHEN a.colorder = 1 THEN d.name
  2. ELSE ‘‘
  3. END ,
  4. 表说明 = CASE WHEN a.colorder = 1 THEN ISNULL(f.value, ‘‘)
  5. ELSE ‘‘
  6. END ,
  7. 字段序号 = a.colorder ,
  8. 字段名 = a.name ,
  9. 标识 = CASE WHEN COLUMNPROPERTY(a.id, a.name, ‘IsIdentity‘) = 1
  10. THEN ‘√‘
  11. ELSE ‘‘
  12. END ,
  13. 主键 = CASE WHEN EXISTS ( SELECT 1
  14. FROM sysobjects
  15. WHERE xtype = ‘PK‘
  16. AND parent_obj = a.id
  17. AND name IN (
  18. SELECT name
  19. FROM sysindexes
  20. WHERE indid IN (
  21. SELECT
  22. indid
  23. FROM sysindexkeys
  24. WHERE id = a.id
  25. AND colid = a.colid ) ) )
  26. THEN ‘√‘
  27. ELSE ‘‘
  28. END ,
  29. 类型 = b.name ,
  30. 占用字节数 = a.length ,
  31. 长度 = COLUMNPROPERTY(a.id, a.name, ‘PRECISION‘) ,
  32. 小数位数 = ISNULL(COLUMNPROPERTY(a.id, a.name, ‘Scale‘), 0) ,
  33. 允许空 = CASE WHEN a.isnullable = 1 THEN ‘√‘
  34. ELSE ‘‘
  35. END ,
  36. 默认值 = ISNULL(e.text, ‘‘) ,
  37. 字段说明 = ISNULL(g.[value], ‘‘)
  38. FROM syscolumns a
  39. LEFT JOIN systypes b ON a.xusertype = b.xusertype
  40. INNER JOIN sysobjects d ON a.id = d.id
  41. AND d.xtype = ‘U‘
  42. AND d.name <> ‘dtproperties‘
  43. LEFT JOIN syscomments e ON a.cdefault = e.id
  44. LEFT JOIN sys.extended_properties g ON a.id = G.major_id
  45. AND a.colid = g.minor_id
  46. LEFT JOIN sys.extended_properties f ON d.id = f.major_id
  47. AND f.minor_id = 0
  48. WHERE d.name = ‘TableName‘ --如果只查询指定表,加上此红色where条件,tablename是要查询的表名;去除红色where条件查询说有的表信息
  49. ORDER BY a.id ,
  50. a.colorder

 

SQL SERVER性能优化SQL

原文:https://www.cnblogs.com/lonelyxmas/p/12382606.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!