SQLServer性能优化之 nolock,大幅提升数据库查询性能
公司数据库随着时间的增长,数据越来越多,查询速度也越来越慢。进数据库看了一下,几十万调的数据,查询起来确实很费时间。 要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑。其实除了index的建立之外,当我们在下SQL Command时,在语法中
公司数据库随着时间的增长,数据越来越多,查询速度也越来越慢。进数据库看了一下,几十万调的数据,查询起来确实很费时间。
要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑。其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询的环境中数据集被LOCK的现象藉此改善查询的效能。
不过有一点千万要注意的就是,WITH (NOLOCK)的SQL SELECT有可能会造成Dirty Read,就是读到无效的数据。
下面对于SQLSERVER的锁争用及nolock,rowlock的原理及使用作一个简单描述:
锁争用的描述
那些不仅仅使用行级锁的数据库使用一种称为混和锁(lock escalation)的技术来获取较高的性能。除非很明确知道是针对整个数据表,否则这些数据库的做法是开始使用行级锁, 然后随着修改的数据增多,开始使用大范围的锁机制。
不幸的是,这种混和锁的方法会产生和放大新的问题:死锁。如果两个用户以相反的顺序修改位于不同表的记录,而这两条记录虽然逻辑上不相关, 但是物理上是相邻的,操作就会先引发行锁,然后升级为页面锁。这样, 两个用户都需要对方锁定的东西,就造成了死锁。
例如:
用户A修改表A的一些记录,引发的页面锁不光锁定正在修改的记录,还会有很多其它记录也会被锁定。
用户B修改表B的一些记录,引发的页面锁锁定用户A和其它正在修改的数据。
用户A想修改用户B在表B中锁定(并不一定正在修改的)数据。
用户B想修改或者仅仅想访问用户A在表A中锁定(并不一定正在修改)的数据。
为了解决该问题,数据库会经常去检测是否有死锁存在,如果有,就把其中的一个事务撤销,好让另一个事务能顺利完成。一般来说,都是撤销 那个修改数据量少的事务,这样回滚的开销就比较少。使用行级锁的数据库 很少会有这个问题,因为两个用户同时修改同一条记录的可能性极小,而且由于极其偶然的修改数据的顺序而造成的锁也少。
而且,数据库使用锁超时来避免让用户等待时间过长。查询超时的引入也是为了同样目的。我们可以重新递交那些超时的查询,但是这只会造成数据库的堵塞。如果经常发生超时,说明用户使用SQL Server的方式有问题。正常情况是很少会发生超时的。
在服务器负载较高的运行环境下,使用混合锁的SQL Server锁机制,表现不会很好。 原因是锁争用(Lock Contention)。锁争用造成死锁和锁等待问题。在一个多用户系统中,很多用户会同时在修改数据库,还有更多的用户在同时访问数据库,随时会产生锁,用户也争先恐后地获取锁以确保自己的操作的正确性,死锁频繁发生,这种情形下,用户的心情可想而知。
确实,如果只有少量用户,SQL Server不会遇到多少麻烦。内部测试和发布的时候,由于用户较少,也很难发现那些并发问题。但是当激发几百个并发,进行持续不断地INSERT,UPDATE,以及一些 DELETE操作时,如何观察是否有麻烦出现,那时候你就会手忙脚乱地去解锁。
锁争用的解决方法
SQL Server开始是用行级锁的,但是经常会扩大为页面锁和表锁,最终造成死锁。
即使用户没有修改数据,SQL Server在SELECT的时候也会遇到锁。幸运的是,我们可以通过SQL Server 的两个关键字来手工处理:NOLOCK和ROWLOCK。
它们的使用方法如下:
<span>SELECT</span> <span>COUNT</span><span>(UserID) </span><span>FROM</span> Users <span>WITH</span><span> (NOLOCK) </span><span>WHERE</span> Username <span>LIKE</span> <span>'</span><span>football</span><span>'</span>
和
<span>UPDATE</span> Users <span>WITH</span><span> (ROWLOCK) </span><span>SET</span> Username <span>=</span> <span>'admin</span><span>'</span> <span>WHERE</span> Username <span>=</span> <span>'</span><span>football</span><span>'</span>
NOLOCK的使用
NOLOCK可以忽略锁,直接从数据库读取数据。这意味着可以避开锁,从而提高性能和扩展性。但同时也意味着代码出错的可能性存在。你可能会读取到运行事务正在处理的无须验证的未递交数据。 这种风险可以量化。
ROWLOCK的使用
ROWLOCK告诉SQL Server只使用行级锁。ROWLOCK语法可以使用在SELECT,UPDATE和DELETE语句中,不过 我习惯仅仅在UPDATE和DELETE语句中使用。如果在UPDATE语句中有指定的主键,那么就总是会引发行级锁的。但是当SQL Server对几个这种UPDATE进行批处理时,某些数据正好在同一个页面(page),这种情况在当前情况下 是很有可能发生的,这就象在一个目录中,创建文件需要较长的时间,而同时你又在更新这些文件。当页面锁引发后,事情就开始变得糟糕了。而如果在UPDATE或者DELETE时,没有指定主键,数据库当然认为很多数据会收到影响,那样 就会直接引发页面锁,事情同样变得糟糕。
下面写一个例子,来说明一下NOLOCK的作用,这里使用一个有一万多条的数据库来测试,先不用NOLOCK来看一下:
<span>declare</span> <span>@start</span> <span>DATETIME</span><span>; </span><span>declare</span> <span>@end</span> <span>DATETIME</span><span>; </span><span>SET</span> <span>@start</span> <span>=</span> <span>getdate</span><span>(); </span><span>select</span> <span>*</span> <span>from</span> Captions_t18<span>; </span><span>SET</span> <span>@end</span> <span>=</span> <span>getdate</span><span>(); </span><span>select</span> <span>datediff</span>(ms,<span>@start</span>,<span>@end</span>);
这里为了是效果更加明显,使用了Select * ,来看一下执行结果,如下图:
这里显示的使用时间是34720ms,下面使用NOLOCK来看一下:
<span>declare</span> <span>@start</span> <span>DATETIME</span><span>; </span><span>declare</span> <span>@end</span> <span>DATETIME</span><span>; </span><span>SET</span> <span>@start</span> <span>=</span> <span>getdate</span><span>(); </span><span>select</span> <span>*</span> <span>from</span> Captions_t18 <span>with</span><span> (NOLOCK); </span><span>SET</span> <span>@end</span> <span>=</span> <span>getdate</span><span>(); </span><span>select</span> <span>datediff</span>(ms,<span>@start</span>,<span>@end</span>);
运行结果如下图:
这次使用的时间是2563ms,差距体现出来了吧。个人感觉时间不应该差这么多,总之性能是提高了不少。大家多多测试看看吧~~
参考文章:http://blog.sina.com.cn/s/blog_7034dbe00100ll9n.html

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

不同Java框架的性能对比:RESTAPI请求处理:Vert.x最佳,请求速率达SpringBoot2倍,Dropwizard3倍。数据库查询:SpringBoot的HibernateORM优于Vert.x及Dropwizard的ORM。缓存操作:Vert.x的Hazelcast客户机优于SpringBoot及Dropwizard的缓存机制。合适框架:根据应用需求选择,Vert.x适用于高性能Web服务,SpringBoot适用于数据密集型应用,Dropwizard适用于微服务架构。

时间复杂度衡量算法执行时间与输入规模的关系。降低C++程序时间复杂度的技巧包括:选择合适的容器(如vector、list)以优化数据存储和管理。利用高效算法(如快速排序)以减少计算时间。消除多重运算以减少重复计算。利用条件分支以避免不必要的计算。通过使用更快的算法(如二分搜索)来优化线性搜索。

优化C++多线程性能的有效技术包括:限制线程数量,避免争用资源。使用轻量级互斥锁,减少争用。优化锁的范围,最小化等待时间。采用无锁数据结构,提高并发性。避免忙等,通过事件通知线程资源可用性。

根据基准测试,对于小型、高性能应用程序,Quarkus(快速启动、低内存)或Micronaut(TechEmpower优异)是理想选择。SpringBoot适用于大型、全栈应用程序,但启动时间和内存占用稍慢。

在开发高性能应用程序时,C++的性能优于其他语言,尤其在微基准测试中。在宏基准测试中,其他语言如Java和C#的便利性和优化机制可能表现更好。在实战案例中,C++在图像处理、数值计算和游戏开发中表现出色,其对内存管理和硬件访问的直接控制带来明显的性能优势。

在Go中生成随机数的最佳方法取决于应用程序所需的安全性级别。低安全性:使用math/rand包生成伪随机数字,适合大多数应用程序。高安全性:使用crypto/rand包生成加密安全的随机字节,适用于需要更强随机性的应用程序。

2025年全球数字虚拟币交易平台竞争激烈,本文根据交易量、安全性、用户体验等指标,权威发布2025年全球十大数字虚拟币交易平台排行榜。OKX凭借强大的技术实力和全球化运营策略居首,Binance以高流动性和低费用紧随其后。Gate.io、Coinbase、Kraken等平台凭借各自优势稳居前列。榜单涵盖Huobi、KuCoin、Bitfinex、Crypto.com和Gemini等交易平台,各有特色,但投资需谨慎。选择平台需考虑安全性、流动性、费用、用户体验、币种选择及监管合规性等因素,理性投资

近日,《黑神话:悟空》在全球范围内都引发了巨大的关注,各平台的同时在线人数都再创新高,这款游戏在多个平台取得了巨大的商业成功。《黑神话:悟空》的Xbox版延期虽然《黑神话:悟空》已于PC和PS5平台发布,但其Xbox版一直没有确切消息。据了解,官方已确认《黑神话:悟空》将登陆Xbox平台。但具体上线日期尚未公布。最近有消息称,Xbox版的延期是由于技术问题所致。据相关博主透露,他在Gamescom期间与开发人员和"Xbox内部人士"的交流中得知,《黑神话:悟空》的Xbox版存
