alt

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)会导致各种问题,但是并不代表其无用,它的使用场景有如下三种:

  1. 数据的使用场景是允许脏数据存在的情况,例如:A和B同时对某张表进行修改操作,但是A和B谁提交都行,且提交一次,另外的人就不允许提交了或者允许多次修改。

  2. 如果只追求性能,不考虑数据安全性,那么可以使用此方法。

  3. 历史数据或不允许进行修改的事实表,可以使用此方法提高查询性能。

使用实例

例子:

查询数据库中的某张表,使用WITH(NOLOCK)。

SELECT TOP (1000) [Date]
      ,[Year]
      ,[Quarter]
      ,[Month]
      ,[Day]
      ,[DATEKEY]
  FROM [CaseData].[dbo].[Dim_Date] WITH(NOLOCK)

结果如下:

alt

alt

alt

这里是白茶,一个PowerBI的初学者。 alt