WITH(NOLOCK)
企业在搭建数仓的时候,对于数仓的负载性能和运行速度都是纳入考量标准的。特别是并发性较高的情况下,如何规避因用户使用量较多而导致死锁卡死的问题呢?其实,这些可以通过WITH(NOLOCK)来解决。
WITH(NOLOCK)顾名思义,不锁的意思。它的目的是为了避免因为查询表,而导致表被锁死,从而提高查询的速度。
WITH(NOLOCK)有两个特点:
1.使用WITH(NOLOCK)查询时,不会被其他排他锁阻拦;
2.使用WITH(NOLOCK)查询时,不会发布锁,阻拦其他事务操作。
概念延申
当数据库中并发较高的时候,容易出现以下几类现象:
-
**脏读:**指某张表,被A管理员读取访问,并且进行了修改,但是还没有进行提交操作;而同时B管理员也读取了这个数据,这种情况下,B读到的是未更新的数据,也被称为脏数据。依据脏数据进行后续的操作,肯定是不对的。
-
**不可重复读:**指的是某个事务中,多次对某张表进行读取操作,在A事务进程还没结束的情况下,B事务对数据进行了修改,这样A事务两次读取到的数据不一致,这种情况就是不可重复读。
PS:通常发生在两个SQL工程师,同时开发的过程中。
- **幻读:**一个事务查询某张表,两次读取到的数据总量不一致,这种情况下就称为幻读。
数据库为了避免上述的三种情况,有4种特殊的隔离机制,分别是:Read uncommitted(读未提交),Read committed(读已提交),Repeatable read(可重复读),Serizable(序列化)。
4种机制可解决的场景如下:
类型 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | √ | √ | √ |
Read committed | √ | √ | |
Repeatable read | √ | ||
Serizable | |||
看到这里,可能小伙伴们会很懵,为什么会讲到这里? |
因为WITH(NOLOCK)的效果,等同于Read uncommitted,使用了WITH(NOLOCK)虽然可以解决并发导致的性能问题,但是会导致脏读、不可重复读、幻读这三种情况的产生。
虽然使用WITH(NOLOCK)会导致各种问题,但是并不代表其无用,它的使用场景有如下三种:
-
数据的使用场景是允许脏数据存在的情况,例如:A和B同时对某张表进行修改操作,但是A和B谁提交都行,且提交一次,另外的人就不允许提交了或者允许多次修改。
-
如果只追求性能,不考虑数据安全性,那么可以使用此方法。
-
历史数据或不允许进行修改的事实表,可以使用此方法提高查询性能。
使用实例
例子:
查询数据库中的某张表,使用WITH(NOLOCK)。
SELECT TOP (1000) [Date]
,[Year]
,[Quarter]
,[Month]
,[Day]
,[DATEKEY]
FROM [CaseData].[dbo].[Dim_Date] WITH(NOLOCK)
结果如下:
这里是白茶,一个PowerBI的初学者。