sql server 性能调优 资源等待之PAGEIOLATCH

by admin on 2019年10月7日

 一.概念

 
 SOS_SCHEDULER_YIELD等待类型是一个任务自愿放弃当前的资源占用,让给其他任务使用。 
 这个等待类型与CPU有直接关系,与内存与也有间接关系,与CPU有关系是因为在sql
server里是通过任务调度SCHEDULER来关联CPU。
通过SCHEDULER下的Worker线程来处理SQL任务。为什么跟内存有关系呢,是因为获取的资源需要内存来承载。 
  Yelding的发生:是指SCHEDULER上运行的Worker都是非抢占式的, 在
SCHEDULER上Worker由于资源等待,让出当前Worker给其它Worker就叫Yielding。
关于SCHEDULER_YIELD产生的原理查看  sqlserver
任务调度与CPU。SOS_SCHEDULER_YIELD 等待的情况可以了解到:

  (1)CPU有压力

  (2) SQL Server CPU scheduler 使用得当处理就会效率高。

1.1 从实例级别来查看等待数

select wait_type,
waiting_tasks_count,
wait_time_ms ,
max_wait_time_ms,
signal_wait_time_ms
from sys.dm_os_wait_stats
where wait_type like 'SOS_SCHEDULER_YIELD%' 
order by wait_type

  查询如下图所示: 

奥门威尼斯网址 1

  这个等待类型排名第二,从请求的次数来说有69367060次,也就是说该线程用完了4ms的时间片,主动放弃cpu。如果没有大量的runnable队列或者大量的signal
wait,证明不一定是cpu问题。因为这两个指标是cpu压力的一个体现
。需要检查执行计划中是否存在大量扫描操作。

1.2 通过dmv scheaduler的描述查看cpu压力

SELECT scheduler_id, current_tasks_count, runnable_tasks_count, work_queue_count, pending_disk_io_count
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255

  如下图所示:

奥门威尼斯网址 2

  如果你注意到runnable_tasks_count计数有两位数,持续很长时间(一段时间内),你就会知道CPU压力。两位数字通常被认为是一件坏事
无法应对当前负荷。另外可以通过性能监视器%Processor Time
来查看CPU的状况。

1.3 通过案例实时查看sql语句级的资源等待

SELECT * FROM sys.dm_exec_requests  WHERE wait_type LIKE 'SOS_SCHEDULER_YIELD%'

  – 或查找资源等待的
  SELECT session_id ,status ,blocking_session_id
  ,wait_type ,wait_time ,wait_resource
  ,transaction_id
  FROM sys.dm_奥门威尼斯网址,exec_requests
  WHERE status = N’suspended’;

  如下图所示
运行sys.dm_exec_requests 表,由于字段多截取了三断。会话202的sql
语句上一次
等待类型是SOS_SCHEDULER_YIELD。之所以会出现YIELD,是因为SCHEDULER下的Worker已经发起了task
命令,但由于资源等待
如锁或者磁盘输入/输出等,Worker又是非抢占式,所以让出了当前的Worker。

奥门威尼斯网址 3

奥门威尼斯网址 4

奥门威尼斯网址 5

1.4 减少sos_scheduler_yield 等待

  正如上面所讨论的,这种等待类型与CPU压力有关。增加更多CPU是简单的解决方案,然而实现这个解决方案并不容易。当这个等待类型很高时,你可以考虑其他的事情。这里通过从缓存中找到与CPU相关的最昂贵的SQL语句。

–查询编译以来 cpu耗时总量最多的前50条(Total_woker_time) 第一种查询
select
‘total_worker_time(ms)’=(total_worker_time/1000),
q.[text], –DB_NAME(dbid),OBJECT_NAME(objectid),
execution_count,
‘max_worker_time(ms)’=(max_worker_time/1000),
‘last_worker_time(ms)’=(last_worker_time/1000),
‘min_worker_time(ms)’=(min_worker_time/1000),
‘max_elapsed_time(ms)’=(max_elapsed_time/1000),
‘min_elapsed_time(ms)’=(min_elapsed_time/1000),
‘last_elapsed_time(ms)’=(last_elapsed_time/1000),
total_physical_reads,
last_physical_reads,
min_physical_reads,
max_physical_reads,
total_logical_reads,
last_logical_reads,
max_logical_reads,
creation_time,
last_execution_time
from
(select top 50 qs.* from sys.dm_exec_query_stats qs order by
qs.total_worker_time desc)
as highest_cpu_queries cross apply
sys.dm_exec_sql_text(highest_cpu_queries.plan_handle) as q
order by highest_cpu_queries.total_worker_time DESC

 

 一.  概述

  这次介绍实例级别资源等待LCK类型锁的等待时间,关于LCK锁的介绍可参考
“sql server
锁与事务拨云见日”。下面还是使用sys.dm_os_wait_stats
来查看,并找出耗时最高的LOK锁。

select wait_type,
waiting_tasks_count,
wait_time_ms ,
max_wait_time_ms,
signal_wait_time_ms
from sys.dm_os_wait_stats
where wait_type like 'LCK%' 
order by  wait_time_ms desc

 查出如下图所示:

奥门威尼斯网址 6

   1.  分析介绍

   重点介绍几个耗时最高的锁含义:

    LCK_M_IX:
正在等待获取意向排它锁。在增删改查中都会有涉及到意向排它锁。
  LCK_M_U: 正在等待获取更新锁。 在修改删除都会有涉及到更新锁。
  LCK_M_S:正在等待获取共享锁。
主要是查询,修改删除也都会有涉及到共享锁。
  LCK_M_X:正在等待获取排它锁。在增删改中都会有涉及到排它锁。
  LCK_M_SCH_S:正在等待获取架构共享锁。防止其它用户修改如表结构。
  LCK_M_SCH_M:正在等待获取架构修改锁 如添加列或删除列
这个时候使用的架构修改锁。

      下面表格是统计分析

锁类型 锁等待次数 锁等待总时间(秒) 平均每次等待时间(毫秒) 最大等待时间
LCK_M_IX 26456 5846.871 221 47623
LCK_M_U 34725 425.081 12 6311
LCK_M_S 613 239.899 391 4938
LCK_M_X 4832 77.878 16 4684
LCK_M_SCH_S 397 77.832 196 6074
LCK_M_SCH_M 113 35.783 316 2268

  注意: wait_time_ms
时间里,该时间表包括了signal_wait_time_ms信号等待时间,也就是说wait_time_ms不仅包括了申请锁需要的等待时间,还包括了线程Runnable
的信号等待。通过这个结论也能得出max_wait_time_ms
最大等待时间不仅仅只是锁申请需要的等待时间。

 

2. 重现锁等待时间

--  重置
DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR);  

 奥门威尼斯网址 7

--  会话1 更新SID=92525000, 未提交
begin tran 
update [dbo].[PUB_StockTestbak] set model='mmtest' where sid=92525000

-- 会话2 查询该ID, 由于会话1更新未提交 占用x锁,这里查询将阻塞
select * from [PUB_StockTestbak] where sid=92525000

   手动取消会话2的查询,占用时间是61秒,如下图:

奥门威尼斯网址 8

  再来统计资源等待LCK,如下图 :

奥门威尼斯网址 9

  总结:可以看出资源等待LCK的统计信息还是非常正确的。所以找出性能消耗最高的锁类型,去优化是很有必要。比较有针对性的解决阻塞问题。

3. 造成等待的现象和原因

现象:

  (1)  用户并发越问越多,性能越来越差。应用程序运行很慢。

  (2)  客户端经常收到错误 error 1222 已超过了锁请求超时时段。

  (3)  客户端经常收到错误 error 1205 死锁。

  (4)  某些特定的sql 不能及时返回应用端。

原因:

  (1) 用户并发访问越多,阻塞就会越来越多。

  (2) 没有合理使用索引,锁申请的数量多。

  (3) 共享锁没有使用nolock, 查询带来阻塞。 好处是必免脏读。

  (4) 处理的数据过大。比如:一次更新上千条,且并发多。

  (5) 没有选择合适的事务隔离级别,复杂的事务处理等。

4.  优化锁的等待时间

   在优化锁等待优化方面,有很多切入点 像前几篇中有介绍
CPU和I/O的耗时排查和处理方案。 我们也可以自己写sql来监听锁等待的sql
语句。能够知道哪个库,哪个表,哪条语句发生了阻塞等待,是谁阻塞了它,阻塞的时间。

  从上面的平均每次等待时间(毫秒),最大等待时间
作为参考可以设置一个阀值。 通过sys.sysprocesses 提供的信息来统计,
关于sys.sysprocesses使用可参考”sql server 性能调优
从用户会话状态分析”。
通过该视图
监听一段时间内的阻塞信息。可以设置每10秒跑一次监听语句,把阻塞与被阻塞存储下来。

   思想如下:

-- 例如 找出被阻塞会话ID 如时间上是2秒 以及谁阻塞了它的会话ID
SELECT spid,blocked #monitorlock FROM sys.sysprocesses 
where blocked>0 and    waittime>2000 

-- 通过while或游标来一行行获取临时表的 会话ID,阻塞ID,通过exec动态执行来获取sql语句文本 进行存储
exec('DBCC INPUTBUFFER('+@spid+')') 

exec('DBCC INPUTBUFFER('+@blocked+')') 

 

一.概念

  在介绍资源等待PAGEIOLATCH之前,先来了解下从实例级别来分析的各种资源等待的dmv视图sys.dm_os_wait_stats。它是返回执行的线程所遇到的所有等待的相关信息,该视图是从一个实际级别来分析的各种等待,它包括200多种类型的等待,需要关注的包括PageIoLatch(磁盘I/O读写的等待时间),LCK_xx(锁的等待时间),WriteLog(日志写入等待),PageLatch(页上闩锁)Cxpacket(并行等待)等以及其它资源等待排前的。 

  1.  下面根据总耗时排序来观察,这里分析的等待的wait_type 不包括以下

SELECT  wait_type ,
        waiting_tasks_count,
        signal_wait_time_ms ,
        wait_time_ms,
        max_wait_time_ms
FROM    sys.dm_os_wait_stats
WHERE   wait_time_ms > 0
        AND wait_type NOT IN ( 'CLR_SEMAPHORE', 'CLR_AUTO_EVENT',
                               'LAZYWRITER_SLEEP', 'RESOURCE_QUEUE',
                               'SLEEP_TASK', 'SLEEP_SYSTEMTASK',
                               'SQLTRACE_BUFFER_FLUSH', 'WAITFOR',
                               'LOGMGR_QUEUE', 'CHECKPOINT_QUEUE',
                               'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT',
                               'BROKER_TO_FLUSH', 'BROKER_TASK_STOP',
                               'CLR_MANUAL_EVENT',
                               'DISPATCHER_QUEUE_SEMAPHORE',
                               'FT_IFTS_SCHEDULER_IDLE_WAIT',
                               'XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN',
                               'SQLTRACE_INCREMENTAL_FLUSH_SLEEP' )
ORDER BY signal_wait_time_ms DESC

  下图排名在前的资源等待是重点需要去关注分析:

奥门威尼斯网址 10

  通过上面的查询就能找到PAGEIOLATCH_x类型的资源等待,由于是实例级别的统计,想要获得有意义数据,就需要查看感兴趣的时间间隔。如果要间隔来分析,不需要重启服务,可通过以下命令来重置

DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR);  

  wait_type:等待类型
  waiting_tasks_count:该等待类型的等待数
  wait_time_ms:该等待类型的总等待时间(包括一个进程悬挂状态(Suspend)和可运行状态(Runnable)花费的总时间)
  max_wait_time_ms:该等待类型的最长等待时间
  signal_wait_time_ms:正在等待的线程从收到信号通知到其开始运行之间的时差(一个进程可运行状态(Runnable)花费的总时间)
  io等待时间==wait_time_ms – signal_wait_time_ms

一.概述

一.概述

  在前几章介绍过 sql server
性能调优资源等待之PAGEIOLATCH,PAGEIOLATCH是出现在sql
server要和磁盘作交互的时候,所以加个IO两个字。这次来介绍PAGELATCH。PAGELATCH类型是sqlserver在缓冲池里的数据页面上经常加的另一类latch锁。

  既然缓冲池里的数据页面与PAGELATCH有关系,那先来介绍数据页面。

  1. 数据页面

  数据页面在”sql server 索引阐述系列二
索引存储结构”中有详细介绍,这里讲与PAGELATCH有关的知识点。
一个页面包含页头,数据存储,页尾偏移量。
在页头里包含了页面属性,页面编号,记录了当前页面空闲的起始位置,当sqlserver
在要插入的时候,就能够很快地找到插入的位置,而页尾的偏移量记录了每一条数据行所有页中的位置,当需要查找页中数据时,通过页尾的偏移量很快能定位。

  当数据行发生变化时, sql
server不但要去修改数据本身,还要维护页中数据行与偏移量的关系。

       2.  PAGELATCH

  讲了这么多关于数据页面, 现在来理清一下关系,
lock锁是保证数据页中数据的逻辑关系,PAGEIOLATCH的latch锁是保证数据页与磁盘进行存储的关系, 
PAGELATCH的latch锁是保证数据页中数据行与页尾的偏移量的关系。当然这种区别介绍是为了更好的去理解它们之间的关系,PAGELATCH作用并不只是这点,
它还会维护系统页面如SGAM,PFS,GAM页面等。

  3. HotPage现象

  当我们为一个表创建主键自增ID时, 那么sql
server将按照ID字段的值顺序进行存储,在大并发下,为了保证ID值按顺序存放在数据页中,这时PAGELATCH就会latch锁住数据页面里的存储结构,
使ID值排队保持先后顺序 。测试Hotpage现象可以是程序后端并发插入或使用
SQLIOSim工具来并发测试。

      下面来看一个简单的图:当前表里有一个page 100的页面,
该页中已有二行数据(rid1和rid2) 分别对应着页尾的偏移量1和2。
这时有二个插入任务,同时插入到page100页,假设第一个任务申请到了ex_latch锁,第二个任务就会等待,使数据行和偏移量对一
一对应。

  奥门威尼斯网址 11

  由于数据页的改动都是在内存中完成的,所以每次修改时间都应该非常短,几乎可以忽略。如果该资源成为了sql
server等待的瓶颈有以下几种情况:

  (1) sql server 没有的明显的内存和磁盘瓶颈。

       (2) 大量的并发集中在表里的一个数据页上叫hotpage

       (3) tempdb
临时表也可以会成为瓶颈,通常可以通过增加tempdb文件来缓解。
具体查看Tempdb怎么会成为性能瓶颈?。

     4. 查看PAGELATCH现象

       4.1 通过sys.dm_exec_query_stats来查看实例级别的等待

select wait_type,
waiting_tasks_count,
wait_time_ms ,
max_wait_time_ms,
signal_wait_time_ms
from sys.dm_os_wait_stats
where wait_type like 'pagelatch%' 
order by  wait_time_ms desc

  奥门威尼斯网址 12

         在实例级别中等待次数最多的是PAGELATCH_EX的latch 排它锁,
平均每次耗时90毫秒,这个平均值应该是不会有性能问题。

       4.2 能过sys.dm_exec_requests 来实时查看sql语句级,
可以采用不定时监听能过session_id来获取sql
语句所对应的表,以及等待的数据页类型 。

SELECT * FROM sys.dm_exec_requests  WHERE wait_type LIKE 'pagelatch%'

   5.  解决思路

  (1)  通过设计表结构,使hotpage现象由单面的并发访问,分散到多个页面。

  (2)  如果是在identity字段上有瓶颈,
可以创建多个分区,因为每个分区都有自己的存储单位,这样hot
单页现象就分散了。

 

二. PAGEIOLATCH_x

  2.1 什么是Latch

    在sql
server里latch是轻量级锁,不同于lock。latch是用来同步sqlserver的内部对象(同步资源访问),而lock是用来对于用户对象包括(表,行,索引等)进行同步,简单概括:Latch用来保护SQL server内部的一些资源(如page)的物理访问,可以认为是一个同步对象。而lock则强调逻辑访问。比如一个table,就是个逻辑上的概念。关于lock锁这块在”sql server
锁与事务拨云见日”中有详细说明。

  2.2 什么是PageIOLatch 

  当查询的数据页如果在Buffer
pool里找到了,则没有任何等待。否则就会发出一个异步io操作,将页面读入到buffer
pool,没做完之前,连接会保持在PageIoLatch_ex(写)或PageIoLatch_sh(读)的等待状态,是Buffer
pool与磁盘之间的等待。它反映了查询磁盘i/o读写的等待时间。
  当sql
server将数据页面从数据文件里读入内存时,为了防止其他用户对内存里的同一个数据页面进行访问,sql
server会在内存的数据页同上加一个排它锁latch,而当任务要读取缓存在内存里的页面时,会申请一个共享锁,像是lock一样,latch也会出现阻塞,根据不同的等待资源,等待状态有如下:PAGEIOLATCH_DT,PAGEIOLATCH_EX,PAGEIOLATCH_KP,PAGEIOLATCH_SH,PAGEIOLATCH_UP。重点关注PAGEIOLATCH_EX(写入)和PAGEIOLATCH_SH(读取)二种等待。

2.1  AGEIOLATCH流程图

  有时我们分析当前活动用户状态下时,一个有趣的现象是,有时候你发现某个SPID被自己阻塞住了(通过sys.sysprocesses了查看)
为什么会自己等待自己呢? 这个得从SQL server读取页的过程说起。SQL
server从磁盘读取一个page的过程如下:

奥门威尼斯网址 13

奥门威尼斯网址 14

  (1):由一个用户请求,获取扫描X表,由Worker x去执行。

  (2):在扫描过程中找到了它需要的数据页同1:100。

  (3):发面页面1:100并不在内存中的数据缓存里。

  (4):sql
server在缓冲池里找到一个可以存放的页面空间,在上面加EX的LATCH锁,防止数据从磁盘里读出来之前,别人也来读取或修改这个页面。

  (5):worker x发起一个异步i/o请求,要求从数据文件里读出页面1:100。

  (6):由于是异步i/o(可以理解为一个task子线程),worker
x可以接着做它下面要做的事情,就是读出内存中的页面1:100,读取的动作需要申请一个sh的latch。

  (7):由于worker
x之前申请了一个EX的LATCH锁还没有释放,所以这个sh的latch将被阻塞住,worker
x被自己阻塞住了,等待的资源就是PAGEIOLATCH_SH。

  最后当异步i/o结束后,系统会通知worker
x,你要的数据已经写入内存了。接着EX的LATCH锁释放,worker
x申请得到了sh的latch锁。

总结:首先说worker是一个执行单元,下面有多个task关联Worker上,
task是运行的最小任务单元,可以这么理解worker产生了第一个x的task任务,再第5步发起一个异步i/o请求是第二个task任务。二个task属于一个worker,worker
x被自己阻塞住了。 关于任务调度了解查看sql server
任务调度与CPU。

 2.2 具体分析

  通过上面了解到如果磁盘的速度不能满足sql
server的需要,它就会成为一个瓶颈,通常PAGEIOLATCH_SH
从磁盘读数据到内存,如果内存不够大,当有内存压力时候它会释放掉缓存数据,数据页就不会在内存的数据缓存里,这样内存问题就导致了磁盘的瓶颈。PAGEIOLATCH_EX是写入数据,这一般是磁盘的写入速度明显跟不上,与内存没有直接关系。

下面是查询PAGEIOLATCH_x的资源等待时间:

select wait_type,
waiting_tasks_count,
wait_time_ms ,
max_wait_time_ms,
signal_wait_time_ms
from sys.dm_os_wait_stats
where wait_type like 'PAGEIOLATCH%' 
order by wait_type

下面是查询出来的等待信息:

PageIOLatch_SH
总等待时间是(7166603.0-15891)/1000.0/60.0=119.17分钟,平均耗时是(7166603.0-15891)/297813.0=24.01毫秒,最大等待时间是3159秒。

PageIOLatch_EX 总等待时间是(3002776.0-5727)/1000.0/60.0=49.95分钟,   
平均耗时是(3002776.0-5727)/317143.0=9.45毫秒,最大等待时间是1915秒。

奥门威尼斯网址 15

关于I/O磁盘 sys.dm_io_virtual_file_stats 函数也做个参考

SELECT  
       MAX(io_stall_read_ms) AS read_ms,
         MAX(num_of_reads) AS read_count,
       MAX(io_stall_read_ms) / MAX(num_of_reads) AS 'Avg Read ms',
         MAX(io_stall_write_ms) AS write_ms,
        MAX(num_of_writes) AS write_count,
         MAX(io_stall_write_ms) /  MAX(num_of_writes) AS 'Avg Write ms'
FROM    sys.dm_io_virtual_file_stats(null, null)
WHERE   num_of_reads > 0 AND num_of_writes > 0 

奥门威尼斯网址 16

  总结:PageIOLatch_EX(写入)跟磁盘的写入速度有关系。PageIOLatch_SH(读取)跟内存中的数据缓存有关系。通过上面的sql统计查询,从等待的时间上看,并没有清晰的评估磁盘性能的标准,但可以做评估基准数据,定期重置,做性能分析。要确定磁盘的压力,还需要从windows系统性能监视器方面来分析。
关于内存原理查看”sql server
内存初探“磁盘查看”sql
server I/O硬盘交互” 。

   CXPACKET是指:线程正在等待彼此完成并行处理。什么意思呢? 当sql
server发现一条指令复杂时,会决定用多个线程并行来执行,由于某些并行线程已完成工作,在等待其它并行线程来同步,这种等待就叫CXPACKET。

  为什么会有并行线程呢?  因为在sql server
里有个任务调度SCHEDULER是跟操作系统CPU个数 默认是一 一匹配的, 
我们也可能通过sp_configure来设置最大并行度,也就是Max Degree of Parallelism
(MAXDOP)。 关于调度可参考” sql server
任务调度与CPU”

  并行处理的优势:
用多个线程来执行一个指令,当sql
server发现一条指令复杂时或语句中含有大数据量要处理,此时执行计划会决定用多个线程并行来执行,从而提高整体响应时间,例如一个指令读入100w条记录,
如果用一个线程做 可能需要10秒, 如果10个线程来做
可能只需要1秒,加上线程间同步时间也不过2秒。

  并行处理的劣势:1是并行线程要等待同步。2是由于这10个线程全力以赴,就有10个对应的cpu,这样别的用户发过来的指令就会受到影响,甚至拿不到cpu来执行。所以对于并发度要求高的需要及时响应的,一般会建议手动设置每个指令的并行线程数。反之可以不设置Max
Degree of Parallelism由系统默认去并行或者设少一点并行度。

   1.1 
 查询 CXPACKET的等待

  借助上一次性能调优的资源等待统计图,会发现等待时间最长的就是CXPACKET类型。

  奥门威尼斯网址 17

 1.2  模拟CXPACKET的并行处理 

     下面是一个分组查询,在执行计划中看到,以采用了并行处理

 奥门威尼斯网址 18

  下面是通过sys.dm_os_waiting_tasks 来查看该语句的task任务。

奥门威尼斯网址 19

 或采用sys.sysprocesses查看结果。下面一个举例中
会话session是SPID 56。 这里我们明显看到,SQL Server使用了5个线程kpid
来执行这个query。

    奥门威尼斯网址 20

 1.3  分析CXPACKET的并行处理

  由于并行的原因而从出现了Expacket
的等待。是否并行的执行,通过执行计划可以查看到,下面是查询大表中的数据,sql
server自动加启了并行执行。

   奥门威尼斯网址 21

  奥门威尼斯网址 22

  共调用了32个线程来并行查询

  奥门威尼斯网址 23奥门威尼斯网址 24

1.4  控制CXPACKET并行度

   有时后台执行的sql, 对于并发度要求不高, 
不需要及时响应的,一般会建议手动设置每个指令的并行线程数。

  奥门威尼斯网址 25

    设置可以发现并行度就二个线程。

    奥门威尼斯网址 26

1.5  CXPACKET资源等待总结

 (1)
通过实例级别查出CXPACKET的等待时间包括总等时间,平均等待时间,最大等待时间。

 (2) 查看并行的前十条语句
(这种查询不建议使用,因为条件是查找含有并行parallel的执行计划,查询响应很慢)。

SELECT TOP 10
        p.* ,
        q.* ,
        qs.* ,
        cp.plan_handle
FROM    sys.dm_exec_cached_plans cp
        CROSS APPLY sys.Dm_exec_query_plan(cp.plan_handle) p
        CROSS APPLY sys.Dm_exec_sql_text(cp.plan_handle) AS q
        JOIN sys.dm_exec_query_stats qs ON qs.plan_handle = cp.plan_handle
WHERE   cp.cacheobjtype = 'Compiled Plan'
        AND p.query_plan.value('declare namespace p="http://schemas.microsoft.com/SQL Server/2004/07/showplan";
max(//p:RelOp/@Parallel)', 'float') > 0
OPTION  ( MAXDOP 1 )

 (3) 找出cpu和i/o耗性能最高的sql语句, 查看执行计划是否有并行处理。

 (4)  找出程序中感觉复杂的sql语句,查看执行计划。

 (5)  避免或减少白天执行频繁复杂sql,优化sql 建好索引。

 (6)  当执行计划发现并不需要用并行执行时,强制sql 使用OPTION ( MAXDOP x)
也不会采用并行执行。

最后考虑调整并行度的开销阈值或降低并行度。

  设置sql语句级的MAXDOP。如果MAXDOP=1的话,使得一个BATCH只对应一个TASK。如果没有设置MAXDOP,一个BATCH可能会产生多个TASKS,那么TASK之间的协调,等待等等,将是很大的开销。把MAXDOP设小,能同时减少WORKER的使用量。所以,如果我们看到等待类型为CXPACKET的话,那么我们可以设置MAXDOP,减少并行度。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图