SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
全局流量管理 GTM,标准版 1个月
简介: 原文:SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬。
原文: SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬。正是受大神们无私奉献精神的影响,所以小弟也作为回报,分享一下关于SET STATISTICS IO和SET STATISTICS TIME这两条T_SQL命令,在查询优化性能中的作用。

      首先我想说明一下这篇文章不是关于如何优化SQL Server查询性能的,因为关于这方面的内容太多,太复杂。另外查看很多关于性能优化(该文章中,指的是查询性能)的资料的过程中,发现几乎所有都是用执行时间作为优化指标,但是用执行时间作为性能优劣的指标并不是那么合适。当然,我们优化查询语句的最终目的就是减少查询时间。

      引起查询时间不准确的原因,有以下两个方面:

       1.SQL Server会随着服务器资源的变化,而进行自我调节。

       因为我们通常测试的服务器和实际服务器的环境并不完全相同。例如,我们在一台负载很重的服务器上进行反复的测试。你会发现每次的执行的时间,并不相同,当然差距并不大,但是这个差距足以让我们的性能调节变得困难许多。当然你也可以反复执行求平均值,但是在负载很大的服务器上,你需要一种多么科学的标准来确定执行时间的平均值呢?

      2.SQL Server所要读取的数据,有没有在缓冲区中。

      因为SQL Server 每次读取数据都必须从数据缓冲区中读取,这个也叫逻辑读。如果要读的数据没有在数据缓冲区中,就要从物理磁盘上读取(物理读)。

      以上两个原因都会影响执行查询语句所用的时间。

      说了那么多,那我们该用什么作为性能优化的标准呢?

      1.CPU的占用时间。

       当数据库执行查询语句时,会用到很多服务器的资源。其中一种资源就是CPU的占用时间,如果数据库没有发生任何的改变,反复的运行同一个查询,CPU的占用时间都是十分接近的。

       2.IO操作的次数。

        IO操作的指标有很多,下面会比较详细的描述。

       通过上面的描述,我们知道,一个查询所需要的CPU、IO资源越少,性能就会越好。如果我们按照这个标准来优化查询,那么就会很容易的判断出你的优化措施是降低了性能,还是提高了性能。想到了这,那么我们怎样才能看到我的服务器资源使用情况呢?这个时候我们就想到了SET STATISTICS IO和SET STATISTICS TIME (之前的内容就算是我卖关子了啊,嘿嘿)

        SET STATISTIC IO和SET STATISTIC TIME像很多T_SQL语句那样属于开关命令(自己起得名字,就是用ON和OFF打开和关闭)。缺省状态下是关闭的。接下来我们就开始使用这两个命令了,好期待。

        在这个例子中,我们使用之前建好的Test数据库,使用Person表

        (一)首先我们使用SET STATISTICS TIME

         1.首先,为了使每次的执行都在同一个起点上,我们使用下面的两条命令,来清除SQL Server的数据和过程缓冲区,否则执行的查询结果就没有可比性了。   

DBCC DROPCLEANBUFFERS

DBCC FREEPROCCACHE

          2.执行SET STATISTIC TIME ON 打开CUP统计报表

         这些准备工作完成后,我们可以执行下面查询:

          select  * from Person where ID=50000

          执行完上述命令之后,你可以在消息选项卡中得到下面信息

SQL Server 分析和编译时间:    CPU 时间 = 0 毫秒,占用时间 = 20 毫秒。

SQL Server 分析和编译时间:    CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。

(1 行受影响)

 SQL Server 执行时间:    CPU 时间 = 235 毫秒,占用时间 = 1508 毫秒。

下面我们来详细的分析这些时间信息的含义。

 第一个“SQL Server 分析和编译时间”指的是解析“select  * from Person where ID=50000”这条查询语句,并将解析的结果放到过程缓冲区中,SQL Server使用的CPU运行时间和总的时间。

第二个“SQL Server 分析和编译时间”指的是从过程缓冲区中取出解析结果,并且执行的时间。这个时间会很快。

如果接下来不清空缓冲区而直接运行“select  * from Person where ID=50000”,你会发现SQL Server 分析和编译时间都为0,因为SQL Server这时,会直接使用缓冲区中的解析结果,因此就不需要编译时间。

第三个“SQL Server执行时间”将会是我们最感兴趣的时间,这个时间是执行这次查询使用了多少CPU运行时间和运行查询使用了多少时间。CPU运行时间是对运行查询所需要的CPU资源的一种相对稳定的测量方法,与CPU的忙闲程度没有关系。但是,每次运行查询时这一数字也会有所不同,只是变化的范围很小。总时间是对查询执行所需要的时间(不计算阻塞或读数据的时间),由于服务器上的负载是在不断变化的,因此这一数据的变化范围有时会相当地大。

 由于CPU占用时间是相对稳定的,所以你可以使用这一数据作为衡量你的优化措施是提高了查询性能,还是降低了查询性能。

(二)接下来我们使用SET STATISTICS IO

和上面的准备工作一样,当我们执行完“select  * from Person where ID=50000”时,我们会在消息选项卡中看到以下信息:

(1 行受影响)
表 'Person'。扫描计数 5,逻辑读取 10418 次,物理读取 105 次,预读 10418 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

这里面的一些信息是非常重要的,另一部分则可以不去考虑。

扫描次数:在查询中涉及到的表被访问的次数。在我们的例子中,Person表只被访问了5次,由于查询中不包括连接命令,这一信息并不是十分有用,但如果查询中包含有一个或多个连接,则这一信息是十分有用的。

逻辑读取:这是最有用的数据。我们知道,SQL Server在对任何数据进行操作前,必须先把数据读取到数据缓冲区中。此外,我们也知道SQL Server何时会从数据缓冲区中读取数据,并把数据读取到大小为8k字节的页中。逻辑读取得意思就是指SQL Server为得到查询结果,而必须从数据缓冲区中读取的页数。

SQL Server在执行逻辑读的时候,不会读取比实际结果多或者少的数据,因此在相同的数据集中,执行同一个查询,得到的逻辑读的结果总是相同的。因此,在进行查询优化时逻辑读的值就是来衡量你的优化措施是否可行的一个很好的标准。(在查询时逻辑读越少,其效率就越高,查询速度就越快,反之,就慢)

物理读取:在执行真正的查询操作前,SQL Server必须从磁盘上向数据缓冲区中读取他所需要的数据。在SQL Server开始执行查询前,当它发现要读的数据不再数据缓冲区中时,它会首先把它需要的数据读到数据缓冲区中。物理读取的意思就是指SQL Server把所需数据读到数据缓冲区中时,从物理磁盘上读取的数据页数。

遗憾的是,在我们进行查询优化时,是不需要考虑物理读的。尽管物理读要比逻辑读可能需要更多的服务器资源。因为SQL Server在执行查询时,是不可能通过性能调节而减少物理读的次数的。减少物理读是一项很复杂并且重要的工作,它涉及到的是整个服务器的性能调节,而不仅仅是查询性能的调节。在进行查询性能调节时,我们是不能控制数据缓冲区大小或服务器的忙碌程度,以及完成查询所需要的数据是在数据缓冲区还是在磁盘上,唯一我们可以控制的就是得到查询结果多需要执行的逻辑读的次数。因此在进行查询优化时,我们大可不必在意物理读的数据。

预读:指的是SQL Server在进行查询优化前,预测要读取的数据页,根据预读的准确程度,预读可能有用也可能没用。和物理读一样,在我们进行查询优化时是不需要考虑的。

剩下的几个“lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次”意思和前面说的差不多,只是在进行增、删、改的时候IO资源的操作情况。

所以呢,我们在做查询优化的时候,使用SET STATISTICS TIME 和SET STATISTICS IO 是个不错的选择。    

 

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
7天前
|
SQL NoSQL Java
Java使用sql查询mongodb
通过使用 MongoDB Connector for BI 和 JDBC,开发者可以在 Java 中使用 SQL 语法查询 MongoDB 数据库。这种方法对于熟悉 SQL 的团队非常有帮助,能够快速实现对 MongoDB 数据的操作。同时,也需要注意到这种方法的性能和功能限制,根据具体应用场景进行选择和优化。
30 9
|
27天前
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
99 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
2月前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
39 8
|
2月前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
63 4
|
2月前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
5月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
6月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
4月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
254 12
|
5月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
56 2
|
5月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。