返回首页



这是一个8部分组成的系列文章关于加快访问SQL Server数据库的第2部分。该系列产品是根据第8章quot;加快了数据库Accessquot;我的书ASP.NET网站性能的秘密,亚马逊和其他的书网站提供。
{A},我们看到了如何查明失踪指标和昂贵的查询。在这第2部分,我们将找出其他瓶颈,包括锁定问题,缺乏执行计划的重用,碎片,和硬件问题。3至8部分将展示如何解决的瓶颈,我们发现在{A2的}:{A3的}第2部分针对其他瓶颈{A4纸}{A5的}{A6的}{A7的}{A8的}{A9的}
如果你喜欢这篇文章,请{A10的}。锁定
在许多执行查询的数据库,有些疑问,可以尝试访问相同的资源,如表或索引。你不希望一个查询阅读而另一个更新的资源,否则,你可以得到不一致的结果。
为了阻止访问资源的查询,SQL Server的锁资源。这将不可避免地导致一些延误,查询等待一个被释放的锁。为了找出这些延迟是否过高,用PerfMon的数据库服务器上检查下列性能计数器:分类:SQLSERVER:阀门总闩锁等待时间(ms) - 总等待时间为毫秒闩锁在最后一秒。分类:SQLSERVER:锁锁超时/秒 - 每秒锁定请求数,超时。这包括NOWAIT,锁的请求。锁等待时间(毫秒) - 锁在最后一秒的毫秒总等待时间。死锁/秒 - 每秒导致死锁的锁请求的数量。
{A11}与Windows,所以你已经拥有它您的计算机上。发出命令quot; perfmonquo​​t从命令提示。它已载入后,点击工具栏上的加号按钮,然后选择类别 - 如SQLSERVER:闩锁 - 在性能对象下拉,然后添加计数器 - 如等待时间(ms)({A12})。
一共有闩锁等待时间(毫秒)表明SQL Server正在等待自己的同步机制太长。锁超时/秒应该是在正常运行中的0和锁等待时间(毫秒)很低。如果没有他们,查询正在等待锁太长被释放。
最后,死锁/秒的数量应为0。如果没有,你有疑问,等待对方释放锁,防止向前。 SQL Server的最终检测到这种情况,并通过回滚的查询,这意味着浪费时间和浪费的工作之一,它解决。
{A13号}如果您发现锁定问题,你会看到如何确定哪些查询会导致过多的锁等待时间,如何来解决这个问题。执行计划重用
在执行查询时,SQL Server查询优化编译一个符合成本效益的执行计划。这需要很多的CPU周期。正因为如此,SQL Server的缓存在内存中的执行计划,在计划缓存。然后,它尝试,以配合那些已经被缓存传入的查询。
在本节中,你会看到如何衡量如何计划缓存正在使用。如果有改进的余地,你会看到在{A14高速公路}如何解决这一问题。性能计数器
开始检查{A15}在数据库服务器上的下列性能计数器:范畴:处理器(的_Total)%处理器时间 - 时间的百分比,该处理器是忙。分类:SQL Server的SQL统计SQL编译/秒 - 批号编译语句编译每秒。预计将是非常高的服务器后启动。SQL Re-Compilations/sec - 每秒数重新编译。
这些计数器将显示高值,在服务器启动为每个传入的查询需要编译。坐在计划缓存在内存中,所以不下去重新启动。在正常运行在一个系统里的数据没有太大变化,您希望每秒汇编小于100,并重新编译每秒接近零。
然而,在一个非常动荡的数据系统,它会是正常的,这些数字要高得多。正如你将看到在{A16},修复丢失的索引,查询最优化的执行计划取决于实际数据表中查询访问。因此,当这些数据经常变更,它是有道理的往往也被重新编译,使他们保持最佳的执行计划。
此外,当您更改模式时,你会想到要受这种变化影响执行计划,以及重新编译。dm_exec_query_optimizer_info
另外,看看服务器优化查询所花费的时间。因为查询优化大量CPU的约束,这是几乎所有的CPU所花费的时间。
动态管理视图(DMV)sys.dm_exec_query_optimizer_info为您提供了自上次重新启动服务器的查询优化,并在几秒钟内经过时间平均完成:

SELECT

    occurrence AS [Query optimizations since server restart],

    value AS [Avg time per optimization in seconds], 

    occurrence * value AS [Time spend optimizing since server restart in seconds]

FROM 

    sys.dm_exec_query_optimizer_info

WHERE 

    counter='elapsed time'

运行此查询,稍等片刻,然后再次运行它,发现所花的时间,在此期间优化。务必之间的运行时间来衡量,这样你就可以制定出什么服务器花费的时间比例优化查询。sys.dm_exec_cached_plans
的DMV sys.dm_exec_cached_plans提供执行计划,在计划缓存中的所有信息。你可以结合的DMV sys.dm_exec_sql_text找出如何一个给定的查询计划往往被重用。如果你得到一个繁忙的查询或存储过程的小重用,你得到太少计划缓存中受益:{C}
列OBJTYPE'proc'的存储过程和即席查询的"即席",而列usecounts多久计划已被用于显示。
{A},您看到了如何识别繁忙的查询和存储过程。碎片
磁盘上8KB页面在数据库中的数据和索引组织。一个页面,SQL Server使用或从磁盘上的数据传输的最小单位。当您插入或更新数据时,页面可能会用完的空间。然后,SQL Server创建另一页,一半的现有页面的内容移动到新的页面。这不仅是新的一页,但原来的页面,以及离开的自由空间。这样,如果你保持原来的页面中的数据插入或更新,不分裂一次又一次。
这意味着,许多插入和更新,以及删除后,你会风有很多页的空白处。这需要更多的磁盘空间比实际需要,但更重要的是还减慢阅读,因为SQL Server现在要读更多的页面访问数据。的网页也可能在不同的磁盘上的物理顺序结束比在SQL Server需要读他们的逻辑顺序。作为一个结果,而不是简单地阅读后彼此的每一页的顺序,它需要等待磁头到达下页 - 这意味着更多的延误。
要建立在当前数据库中每个表和索引的碎片级别,使用下面的查询使用的DMV dm_db_index_physical_stats:
SELECT 

    o.name AS TableName, i.name AS IndexName, ips.index_type_desc,

    ips.avg_fragmentation_in_percent, ips.page_count, 

    ips.avg_page_space_used_in_percent

FROM 

   sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'Sampled') ips

   JOIN sys.objects o ON ips.object_id = o.object_id

   JOIN sys.indexes i ON (ips.object_id = i.object_id) AND (ips.index_id = i.index_id)

WHERE 

   (ips.page_count >= 1000) AND (ips.avg_fragmentation_in_percent > 5) AND

   (ips.alloc_unit_type_desc <> 'LOB_DATA') AND   

   (ips.alloc_unit_type_desc <> 'ROW_OVERFLOW_DATA')

ORDER BY 

    o.name, i.name

这使您可以接管1000页,超过5%的零散的所有表和索引。在表和索引,少取碎片的展望超过几千页,往往是在浪费时间。 5%的碎片可能声音小,但碎片可能是在一个表或索引的大量使用面积。
当你看到一个条目中的聚集索引的索引类型,它真的是指实际的表,因为表的聚集索引的一部分。索引类型堆是指一个表没有聚集索引。这是进一步解释{A18}。
如果你发现任何表或索引,是分散的5%以上,并接管几千页,这可能是一个问题。 {A19}将显示如何对表和索引进行碎片整理。请注意,重组不是一个银弹 - 它不一定会解决任何或所有的性能问题。记忆
看看是否内存不足放慢数据库服务器,检查这些计数器:{A15}分类:记忆页/秒 - 服务器内存用完时,它存储的信息暂时磁盘上,然后以后读它需要的时候 - 这是非常昂贵的。此计数器表示,这种情况发生的频率。分类:SQL Server的缓冲区管理页寿命 - 页没有被用来在缓冲池中停留的秒数。更大的寿命,更大的机会SQL Server将能够从一个页面,而不必从磁盘中读取的内存。 缓冲区高速缓存命中率 - 在缓冲池中被发现,而不必从磁盘上读取,页面的百分比。
这些计数器可以告诉你SQL Server是否有内存太少。这将导致它在磁盘上存储更多的数据,导致过多的磁盘I / O,造成更大的CPU和磁盘上的压力。
页/秒,如果是一贯的高,或者缓存命中率始终低于说90%,增加内存可能减轻负载磁盘系统 - 请参阅{A21号}。
如果页面寿命突然变得比它一般存在于你的系统是低得多,并保持低,这将是一个令人担忧。你应该可以忽略临时逢低页寿命。
低页寿命往往造成的,例如,查询做表扫描。在表扫描,SQL Server将读取的页面在内存表扫描每一条记录,和排出的网页时,他们不再需要从内存 - 此页搅动页寿命较短。请注意,这里的解决方案不会增加内存,但为了避免表扫描,例如添加索引 - {A18}。
但是,如果你的系统越来越繁忙时间的推移与页生命预期降低随着时间的推移,它可能是时间添加内存 - 请参阅{A21号}。
除了上面显示的性能计数器,您可以使用的DMV dm_os_sys_memory("SQL Server 2008和更高):{体C3}
的列system_memory_state_desc显示人类可读形式的物理内存的状态。磁盘使用情况
SQL Server是大量磁盘的约束,所以解决磁盘瓶颈,可以使一个很大的区别。如果你发现在上一节的内存不足,解决那些第一,因为内存不足可能会导致过多的磁盘使用本身。否则,这些计数器来检查每个磁盘{A15}一些其他的原因是磁盘瓶颈。关键词:物理磁盘和逻辑磁盘平均。磁盘秒/读 - 从磁盘读取数据的平均时间,以秒。%Disk Time的 - 所选磁盘忙于读或写的时间的百分比。平均。磁盘队列长度 - 平均人数读写采样间隔期间排队的请求。当前的磁盘队列长度 - 当前排队的请求数。
如果平均。磁盘秒/读始终是小于0.02秒,您的磁盘系统需要注意,尤其是如果它是一贯的高超过0.05秒。如果这样下去,在短期内,这可能是一个简单的很多,同时在未来的工作的情况,所以不会是一个值得关注的直接原因。
如果你的系统只有1盘,比%Disk Time的是持续超过85%,严重强调的磁盘系统。然而,如果您使用RAID阵列或SAN,%Disk Time的可能持续超过100%,没有它是一个问题。
平均。磁盘队列长度和当前磁盘队列长度是指在磁盘控制器进行排队或正在处理的任务数。这些计数器是用于SAN,队列长度是难以解释好吗或过高的那么有用。否则,始终大于2的计数器值将是一个问题。如果您使用RAID阵列控制器连接到多个磁盘上,乘由单个磁盘阵列 - 所以,如果有2个阵列中的磁盘,寻找计数器值始终高于4。牢记一些操作一气呵成队列倾倒大量的IO交易,然后等待磁盘系统而做别的事情。
{A21号}将展示如何修复磁盘问题。CPU的
如果你发现在上一节的内存或磁盘问题,解决这些首先是因为他们将CPU以及强调。否则,请检查下面的柜台{A15}看到CPU是否被强调的另一个原因。分类:处理器%处理器时间 - 该处理器是繁忙的时间比例。分类:系统处理器队列长度 - 等待处理的线程数。
如果始终超过75%,或处理器队列长度持续大于2%的处理器时间,CPU可能强调。{A21号}将显示如何解决此问题。结论
在这一部分中,我们看到了如何找准瓶颈,包括锁定的问题,缺乏执行计划的重用,碎片问题和内存,硬盘和CPU的问题。
{A28},我们将开始修复修复任何缺失索引的瓶颈。我们将有深入研究,在如何索引引擎盖下,当工作时,不使用它们。

回答

评论会员:马特Perdeck 时间:2012/02/07
优秀
:约翰・西蒙斯/取缔程序员
评论会员:游客 时间:2012/02/07
{A29}如果你想找到在CodeProject上的文章,只需添加"CodeProject上",无论你在搜索栏键入