SQL Server 利用锁提示优化Row_number()-程序员需知

简介: 原文:SQL Server 利用锁提示优化Row_number()-程序员需知网站中一些老页面仍采用Row_number类似的开窗函数进行分页处理,此时如果遭遇挖坟帖的情形可能就需要漫长的等待且消耗巨大.
原文: SQL Server 利用锁提示优化Row_number()-程序员需知

网站中一些老页面仍采用Row_number类似的开窗函数进行分页处理,此时如果遭遇挖坟帖的情形可能就需要漫长的等待且消耗巨大.这里给大家介绍根据Row_number()特性采用特定锁Hint提升查询速度.

  直接上菜

  脚本环境可在SQL Server优化技巧之SQL Server中的"MapReduce"找到

  如下查询在分页中比较常见

set statistics time on

 select * from 
(
select ProductID, rn = ROW_NUMBER() OVER (ORDER BY ProductID)
from [bigTransactionHistory]
) as t
where t.rn between 15631801 and 15631802

这条查询在我的电脑上执行了15S,这还是数据全在内存中的情形!如图1-1

                                                                图1-1

一个简单的执行计划执行如此之长有点匪夷所思,毕竟逻辑读才6W多,且无物理读

,而且CPU时间与占用时间相差无几,排除了阻塞之类的因素后我们把消耗定位在这个查询本身上.这时提一个Row_number()的特点,它可在万千数据中将其序列化让我们找到我们想要的精确数据点,但就此默认的实现方式上是为每一行数据都加一个行锁.

我们开启Trace Flag 1200再次执行语句捕捉下执行时的锁.可以看到Row_number()在实现上未进行锁升级如图1-2

Code

dbcc traceon(3604,1200,-1)

select * from 
(
select ProductID, rn = ROW_NUMBER() OVER (ORDER BY ProductID)
from [bigTransactionHistory]
) as t
where t.rn between 15631801 and 15631802
View Code

                                                   图1-2

到此我们对此问题的解决方式也就出来了:可采用锁hint的形式手动为其升级

这里我采用页锁,如图1-3

而两者从执行计划上看是相同的,预估也完全一样如图1-4

Code

select * from 
(
select ProductID, rn = ROW_NUMBER() OVER (ORDER BY ProductID)
from [bigTransactionHistory] with(paglock)
) as t
where t.rn between 15631801 and 15631802
View Code

 

                                         图1-3

 

                                                             图1-4

 

可以看到我们通常的查看执行计划的方式在此就不太适合了,需要我们对资源消耗有更详细的认知.

注:平时我们还可用Trace Profiler捕捉锁,但需注意慎用.

   Row_number()默认看不到锁升级,全局性能瓶颈下可能回升级

   如果你的应用不在乎脏读,nolock方式更愉快:)

其它:当数据被更新发生阻塞时,有时业务同事会问到底更新了哪条数据有木有?

这里写了个简单的查询以便找到具体更新被锁住的行,如图2-1

Code

begin tran ttt
update dbo.[bigProduct] set size=111 where ProductID<1100
-- rollback when finish test
--rollback tran ttt

--open another session

SELECT * FROM [bigProduct] with(nolock)
WHERE
    %%LOCKRES%% IN
    (
        SELECT 
            tl.resource_description
        FROM sys.dm_tran_locks AS tl
        INNER JOIN sys.partitions AS t2 ON
            t2.hobt_id = tl.resource_associated_entity_id
        WHERE 
            t2.object_id = OBJECT_ID('bigProduct')
            AND tl.resource_type = 'KEY'
    )

 

                                                          图2-1

 

结语:系统内任何元素都有可能成为影响平衡的绊脚石.找到它,理解它,利用它.

认为有收获的同学请点赞.

目录
相关文章
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
1746 0
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
931 13
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
638 9
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
390 6
|
SQL 存储 数据采集
sql中varchar转number时报错怎么解决
通过上述策略的综合运用,面对VARCHAR到NUMBER的转换挑战,不仅能够游刃有余地解决现有的问题,更能前瞻性地预防未来的隐患。在数字化转型的浪潮中,凭借其高性能、安全稳定的云产品与服务,为各类企业级应用保驾护航,助您轻松驾驭数据的海洋,实现业务的无缝扩展与全球布局。
722 0
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
1445 3
|
SQL 运维 监控
MSSQL性能调优实战:索引策略优化、SQL查询重写与智能锁管理
在Microsoft SQL Server(MSSQL)的运维中,性能调优是确保数据库高效运行、满足业务需求的关键环节
|
SQL 监控 数据库
MSSQL性能调优秘籍:索引深度优化、SQL重构技巧与高效锁策略
在Microsoft SQL Server(MSSQL)环境中,性能调优是确保数据库高效运行、满足业务快速增长需求的关键
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
1440 1