RDS SQL Server - 最佳实践 - 高CPU使用率系列之非SARG查询

简介: # 摘要 阿里云RDS SQL Server客户遇到最多的一个问题便是高CPU使用率导致导致SQL Server服务响应缓慢,查询超时,甚至服务挂起僵死。本系列文章第四篇分析非SARG查询导致CPU的高利用率的解决之道。 # 问题引入 “鸟啊,你听说过RDBMS的非SARG查询语句吗?我还是今天第一次听说呢!”。老鸟有些不解的问菜鸟。 “哈哈,鸟哥,孤陋寡闻,土鳖了吧。它可是导致RDBMS

摘要

阿里云RDS SQL Server客户遇到最多的一个问题便是高CPU使用率导致导致SQL Server服务响应缓慢,查询超时,甚至服务挂起僵死。本系列文章第四篇分析非SARG查询导致CPU的高利用率的解决之道。

问题引入

“鸟啊,你听说过RDBMS的非SARG查询语句吗?我还是今天第一次听说呢!”。老鸟有些不解的问菜鸟。
“哈哈,鸟哥,孤陋寡闻,土鳖了吧。它可是导致RDBMS数据库CPU高使用率的又一个重要的原因呢!今天就让我细细道来。”,菜鸟开始得意忘形起来。”。

场景分析

SARG是Search Argument英文的缩写形式,非SARG简单来说就是指查询谓词(特别是WHERE字句或者连接操作的ON字句)导致索引失效,查询优化器无法使用高效的Index Seek操作,退而求其次的使用效率相对较低的Index Scan操作,从而导致了CPU使用率的上升和查询性能降低。常见的非SARG操作包括在WHERE语句中使用到了标量函数Datediff,Dateadd,Year,Rtrim,Upper,Lower,LIKE完全模糊匹配(格式如LIKE ‘%XXX%’)或者是用户自定义函数等。

解决方法

解决非SARG查询的核心思想是通过查询逻辑的等价改写或者功能设计层面的优化来避免WHERE语句中使用标量函数,我们仅以以下几种常见的非SARG操作来举例说明,其他类推。

DATEDIFF

比如,我们需要查询出当天的订单信息记录,非SARG的写法如下(在WHERE语句中使用了Datediff函数):

USE TestDb
GO

CREATE INDEX IX_OrderDate
ON dbo.SalesOrder([OrderDate])
WITH (FILLFACTOR = 90);
GO

SET STATISTICS TIME ON
SET STATISTICS IO ON

-- find out sales info of today.
SELECT 
    ItemID, OrderQty, Price,OrderDate
FROM dbo.SalesOrder
WHERE DATEDIFF(DAY, OrderDate, GETDATE()) = 0

SET STATISTICS TIME OFF
SET STATISTICS IO OFF

从性能指标来看,I/O消耗为8406,CPU消耗为171毫秒,执行时间消耗为211毫秒,截图如下所示:
01.png

执行计划窗口,SQL Server优化器选择走Index Scan,截图如下:
02.png

其实,我们可以换个思维逻辑想想,当天的数据,其实是指时间大于等于当天凌晨零点零分,并且时间小于等于当前时刻的记录。那么等价逻辑的改写代码如下:

USE TestDb
GO
SET STATISTICS TIME ON
SET STATISTICS IO ON

DECLARE
    @today DATETIME = CONVERT(CHAR(10), GETDATE(), 120)
;
SELECT 
    ItemID, OrderQty, Price,OrderDate
FROM dbo.SalesOrder
WHERE OrderDate >= CONVERT(CHAR(10), GETDATE(), 120)
    AND OrderDate <= GETDATE();
SET STATISTICS TIME OFF
SET STATISTICS IO OFF

优化后性能指标,I/O消耗为3,CPU消耗为0毫秒,执行时间消耗为109毫秒。
03.png

查询优化器选择了更为高效的Index Seek的执行计划操作上来,截图如下:
04.png

从性能指标对比来看,I/O从8406降低到3,CPU消耗从171毫秒降低到0毫秒,执行时间从211降低到109毫秒,特别是I/O和CPU的提升非常明显。

UPPER/LOWER

由于SQL Server默认的排序规则是忽略大小写的,换句话说SQL Server认为UPPER和upper是相等的。所以在做字符串比较运算的时候,可以省略UPPER或者是LOWER函数的使用,以免造成非SARG查询,导致CPU使用率增加。
当然需要特别注意的是:在改写非SARG查询之前需要再次确认你的数据库是忽略大小写的,即含有case-insensitive关键字。检查方法如下:

USE TestDb
GO
EXEC sys.sp_helpsort

结果展示如下图所示:
05.png

RTRIM

有的人在写字符串比较的时候,喜欢使用RTRIM函数来取消字符串最右边的空格后再来比较,其实这种做法是画蛇添足,完全没有必要的。理由是SQL Server在做字符串比较的时候,自动会忽略最右边的空格。这样做反而会导致非SARG查询,CPU使用率增高。
我们可以写一个非常简单的例子来证明这一点,在IF语句中,等号左边的RTRIM后紧跟一个空格符,等号右边的字符串TRIM后不包括空格,但是IF语句的判断结果为真。代码如下所示:

IF 'TRIM ' = 'TRIM'
    PRINT 'equals'
ELSE
    PRINT 'not equal'

结果展示如下图所示:
06.png

LIKE完全模糊匹配

WHERE语句中的LIKE完全模糊匹配,同样会导致SQL Server索引失效,同样也是属于非SARG查询的一种。这种场景的优化包含两种方法:第一种方法是从设计层面来优化,比如:我们经常碰到的场景是通过电话号码来完全模糊查询,但是客户的查询语句往往传入的电话号码又都是一个完整的电话号码。所以这里,我们完全可以将设计修改为电话号码仅支持完整电话号码查询,即将LIKE完全模糊匹配的设计修改成了等于操作方式,避免了非SARG操作;第二种解决方法:如果设计层面无法避免要使用完全模糊匹配查询,可以选择使用SQL Server Fulltext技术来解决LIKE字句完全模糊查询,以此来避免非SARG操作,降低CPU使用率。详情,可以参见文章:SQL Server FullText解决Like字句性能问题

总结

本篇文章分析了非SARG查询语句导致RDS SQL Server CPU使用率增高的原因以及解决这类问题的核心思想是改写语义逻辑,避免非SARG查询导致CPU高使用率,并且举例说明了几个典型的非SARG查询的改写方法。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
SQL 缓存 监控
MySQL缓存机制:查询缓存与缓冲池优化
MySQL缓存机制是提升数据库性能的关键。本文深入解析了MySQL的缓存体系,包括已弃用的查询缓存和核心的InnoDB缓冲池,帮助理解缓存优化原理。通过合理配置,可显著提升数据库性能,甚至达到10倍以上的效果。
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1859 152
|
SQL 存储 关系型数据库
MySQL体系结构详解:一条SQL查询的旅程
本文深入解析MySQL内部架构,从SQL查询的执行流程到性能优化技巧,涵盖连接建立、查询处理、执行阶段及存储引擎工作机制,帮助开发者理解MySQL运行原理并提升数据库性能。
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1263 156
|
SQL 监控 关系型数据库
SQL优化技巧:让MySQL查询快人一步
本文深入解析了MySQL查询优化的核心技巧,涵盖索引设计、查询重写、分页优化、批量操作、数据类型优化及性能监控等方面,帮助开发者显著提升数据库性能,解决慢查询问题,适用于高并发与大数据场景。
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
储存过程(Stored Procedures) 和 函数(Functions) : 储存过程和函数允许用户编写 SQL 脚本执行复杂任务.
428 14
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
以上概述了MySQL 中常见且重要 的几种 SQL 查询及其相关概念 这些知识点对任何希望有效利用 MySQL 进行数据库管理工作者都至关重要
317 15
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
SQL 监控 关系型数据库
查寻MySQL或SQL Server的连接数,并配置超时时间和最大连接量
以上步骤提供了直观、实用且易于理解且执行的指导方针来监管和优化数据库服务器配置。务必记得,在做任何重要变更前备份相关配置文件,并确保理解每个参数对系统性能可能产生影响后再做出调节。
1016 11
|
SQL 关系型数据库 MySQL
MySQL入门指南:从安装到第一个查询
本文为MySQL数据库入门指南,内容涵盖从安装配置到基础操作与SQL语法的详细教程。文章首先介绍在Windows、macOS和Linux系统中安装MySQL的步骤,并指导进行初始配置和安全设置。随后讲解数据库和表的创建与管理,包括表结构设计、字段定义和约束设置。接着系统介绍SQL语句的基本操作,如插入、查询、更新和删除数据。此外,文章还涉及高级查询技巧,包括多表连接、聚合函数和子查询的应用。通过实战案例,帮助读者掌握复杂查询与数据修改。最后附有常见问题解答和实用技巧,如数据导入导出和常用函数使用。适合初学者快速入门MySQL数据库,助力数据库技能提升。

推荐镜像

更多