sql-server – 具有许多并发,长时间运行的查询的SQL Server性能

前端之家收集整理的这篇文章主要介绍了sql-server – 具有许多并发,长时间运行的查询的SQL Server性能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道如何同时执行许多长时间运行的查询将影响sql Server及时为每个查询提供服务的能力.

[编辑]

我不打算模糊,这更像是一个假设.让我们假设查询是select语句,在具有数百万行的表上有某种谓词.

解决方法

中央处理器

每个进入服务器的请求(即每个“批处理”)都将与“任务”相关联,请参阅sys.dm_os_tasks.该任务在“调度程序”上排队,大致说是cpu核心,请参阅sys.dm_os_schedulers.每个调度程序有几个“工人”(即线程或光纤,见sys.dm_os_workers),一个自由工作人员将从调度程序的队列中获取下一个任务并“运行”它,执行它直到任务完成(即请求已完成) ).此调度机制适用于sql内部的所有内容,包括系统任务,CLR运行代码等等.

可以创建的任务数受可用内存的限制.请求(‘批处理’)不会将任务一对一地等同于任务,因为一些请求一旦开始就会安排更多要执行的任务,并行查询就是典型示例.系统中的工作者数量是动态的,但受“最大工作线程”配置设置的限制.如果达到了工作人员上限,则新的计划任务将在调度程序中排队,但在工作人员释放(完成任务)并变为可用之前不会被选中.达到此条件时,称为“工作者饥饿”并导致服务器无响应,因为新客户端登录握手需要执行登录任务(服务器似乎拒绝连接),现有客户端的新请求将排队等待任务(服务器需要很长时间来响应琐碎的请求).

因此,如果您有大量并行,长时间运行的查询,您将消耗大量工作人员执行许多长时间运行的任务.这减少了自由工作者池的大小,从而减少了可用于服务其他即将到达服务器的短任务的工作者(如OLTP请求,登录握手等).服务器似乎没有响应,因为任务堆积在调度程序队列中(这可以在sys.dm_os_schedulers DMV work_queue_count列中看到).在极端情况下,您可以有效地使工作者系统挨饿,使服务器完全没有响应,直到某些工作人员获得自由.

记忆

包含并行操作的查询计划通常与大型索引(大型表)的完整扫描相关联.通过遍历其叶页来完成扫描索引,并且读取大表中的所有叶页意味着在执行查询期间所有这些页必须一次或多次存在于存储器中.这反过来又创建了对缓冲池中的空闲页面的需求,以容纳扫描的页面.对空闲页面的需求产生内存压力,导致通知高速缓存开始驱逐旧条目,并且移除缓冲池中的旧访问数据页面.可以在sys.dm_os_memory_cache_clock_hands中看到缓存通知.可以通过检查good ole’Page Life Expectancy性能计数器来控制数据页驱逐.

驱逐缓存条目的效果是下次需要被驱逐的条目(编译计划,权限标记或其他)时必须从头开始创建,从而导致消耗更多的cpu,内存和IO,这种效果可以即使在长时间运行的查询完成后也会表现出来.

现在可能的情况是,您的系统安装了如此庞大的RAM,扫描几个大表没有区别,您的RAM可以容纳您的整个数据库,有空余.在那种情况下没有问题.但大多数情况并非如此.

IO

这与上面的内容(MEMORY)有关.所有那些满足索引扫描的页面读取都必须转移到内存中,这意味着长时间运行的查询会占用IO带宽的(可能很大)部分.此外,必须将从缓冲池中逐出的所有脏数据页写入磁盘,从而产生更多IO.被驱逐的干净页面很可能在将来的某个时候需要,所以更多IO.

如果扫描生成的IO超出系统带宽,IO操作将开始在磁盘控制器上排队.这可以在Physical Disk/Avg Queue Length性能计数器中轻松检查.

争夺

最后,最大的问题是:锁定争用.如上所述,并行查询几乎总是意味着表扫描.表扫描会在他们访问的每一行上占用共享锁.它确实是在正常操作模式下读取记录后立即释放锁定,但仍然保证您将在表格中的每一行上请求S锁定.这几乎可以保证这些扫描会在更新时锁定X行.当发生这种情况时,扫描必须停止并等待释放X锁,这在更新事务最终提交时发生.结果是,即使是表上适度的OLTP活动也会阻止长时间运行的查询.理想情况下,这就是所发生的一切,结果只是表现不佳.但是如果长时间运行的查询做任何花哨的东西,比如获取页面锁而不是行锁,事情会很快变得丑陋.由于这些扫描端到端地遍历索引,并且保证它们与更新冲突,因此这些查询获取的较高粒度锁不再仅仅与更新锁冲突,但实际上会导致死锁.解释如何发生这种情况超出了本回复的范围.

为了消除争用,当查询合法地执行完全扫描时,最好的选择是使用魔术快照:database snapshots创建用于报告,或使用snapshot isolation级别.请注意,有些人可能会建议使用脏读,我还没有找到一个实际可以接受的情况.

原文链接:https://www.f2er.com/mssql/77819.html

猜你在找的MsSQL相关文章