当前位置: 代码迷 >> Sql Server >> 如何分析sql select 語句的快慢
  详细解决方案

如何分析sql select 語句的快慢

热度:58   发布时间:2016-04-27 17:05:12.0
怎么分析sql select 語句的快慢
SQL查詢語句中,用肉眼怎么分析SQL語句的查詢快慢。。。
 那位高手能幫忙下。。。在線等。。。謝謝。。。
 

------解决方案--------------------
以下几种99.99%的能用性, 特殊情况下可能会有例外嘛

1. 一看见带 not in的语句, 就知道慢
2. 一看见带 cursor的游标就知道占用资源, 速度自然不快
3. 一看见一个语句用了三层以上的子查询就知道效率不行
4. 一看见字段参与的计算表达式放在where条件后的等式左边就知道速度差
5. 一看见where条件后的等式有getdate()就知道不严格, 因为如果有N条记录其实此时getdate()函数是调用N次, 当次没有调用一次快哟
6. 一看动态执行语句(在查询分析器里是红瞎瞎的一片)就知道非常的没有效率,因为根本没有索引优化, 也没有预编译的好处, 有时候的确不得不用动态执行, 尽量用在数据量非常小的场合
------解决方案--------------------
sql查询性能调试,用SET STATISTICS IO和SET STATISTICS TIME

 

set statistics profile on 

set statistics io on 

set statistics time on

一个查询需要的CPU、IO资源越多,查询运行的速度就越慢,因此,描述查询性能调节任务的另一种方式是,应该以一种使用更少的CPU、IO资源的方式重写查询命令,如果能够以这样一种方式完成查询,查询的性能就会有所提高。

如果调节查询性能的目的是让它使用尽可能少的服务器资源,而不是查询运行的时间最短,那么就更容易测试你采取的措施是提高了查询的性能还是降低了查询的性 能。尤其是在资源利用不断变化的服务器上更是如此。首先,需要搞清楚在对查询进行调节时,如何测试我们的服务器的资源使用情况。

在开始我们的例子前,先运行下面的这二条命令(不要在正在使用的服务器上执行),这二条命令将清除SQL Server的数据和过程缓冲区,这样能够使我们在每次执行查询时在同一个起点上,否则,每次执行查询得到的结果就不具有可比性了:DBCC DROPCLEANBUFFERS和DBCC FREEPROCCACHE

输入并运行下面的Transact-SQL命令:

SET STATISTICS IO ON

SET STATISTICS TIME ON

一旦上面的准备工作完成后,运行下面的查询:

SELECT * FROM [order details]

显示结果:

SQL Server parse and compile time: (SQL Server解析和编译时间:)

CPU time = 10 ms, elapsed time = 61 ms. ……(1)

 

SQL Server parse and compile time: (SQL Server解析和编译时间:)

CPU time = 0 ms, elapsed time = 0 ms. ……(2)

 

(所影响的行数为 2155 行) ……(3)

 

Table 'Order Details'. Scan count 1, logical reads 10, physical reads 1, read-ahead reads 9.

(表:Order Details,扫描次数 1,逻辑读 10,物理读 1,提前读取 9) ……(4)

 

SQL Server Execution Times:

(SQL Server执行时间:)

CPU time = 30 ms, elapsed time = 387 ms. ……(5)

标志(1)表示SQL Server解析“ELECT * FROM [order details]”命令并将解析的结果放到SQL Server的过程缓冲区中供SQL Server使用所需要的CPU运行时间和总的时间。

标志(2)表示SQL Server从过程缓冲区中取出解析结果供执行的时间,大多数情况下这二个值都会是0,因为这个过程执行得相当地快。

标志(5)表 示执行这次查询使用了多少CPU运行时间和运行查询使用了多少时间。CPU运行时间是对运行查询所需要的CPU资源的一种相对稳定的测量方法,与CPU的 忙闲程度没有关系。但是,每次运行查询时这一数字也会有所不同,只是变化的范围没有总时间变化大。总时间是对查询执行所需要的时间(不计算阻塞或读数据的 时间),由于服务器上的负载是在不断变化的,因此这一数据的变化范围有时会相当地大。(由于CPU占用时间是相对稳定的,因此可以使用这一数据作为衡量你的调节措施是提高了查询性能还是降低了查询的性能的一种方法。)

标志(4)是SET STATISTICS IO的效果

 

Scan Count:在查询中涉及到的表被访问的次数。在我们的例子中,其中的表只被访问了1次,由于查询中不包括连接命令,这一信息并不是十分有用,但如果查询中包含有一个或多个连接,则这一信息是十分有用的。(一 个循环外部的表的Scan Count值为1,但对于一个循环内的表而言,其值为循环的次数。可以想象得到,对于一个循环内的表而言,其Scan Count值越小,它所使用的资源越少,查询的性能也就越高。因此在调节一个带连接的查询的性能时,需要关注Scan Count的值,在进行调节时,注意观察它是增加还是减少了。)

Logical Reads: 这是SET STATISTICS IO或SET STATISTICS TIME命令提供的最有用的 数据。我们知道,SQL Server在可以对任何数据进行操作前,必须首先把数据读取到其数据缓冲区中。此外,我们也知道SQL Server何时会从数据缓冲区中读取数据,并把数据读取到大小为8K字节的页中。那么Logical Reads的意义是什么呢?Logical Reads是指SQL Server为得到查询中的结果而必须从数据缓冲区读取的页数。在执行查询时,SQL Server不会读取比实际需求多或少的数据,因此,当在相同的数据集上执行同一个查询,得到的Logical Reads的数字总是相同的。(SQL Server执行查询时的Logical Reads值每一次这个数值是不会变化的。因此,在进行查询性能的调节时,这是一个可以用来衡量你的调节措施是否成功的一个很好的标准。如果 Logical Reads值下降,就表明查询使用的服务器资源减少,查询的性能有所提高。如果Logical Reads值增加,则表示调节措施降低了查询的性能。在其他条件不变的情况下,一个查询使用的逻辑读越少,其效率就越高,查询的速度就越快。)

Physical Reads:物 理读,在执行真正的查询操作前,SQL Server必须从磁盘上向数据缓冲区中读取它所需要的数据。在SQL Server开始执行查询前,它要作的第一件事就是检查它所需要的数据是否在数据缓冲区中,如果在,就从中读取,如果不在,SQL Server必须首先将它需要的数据从磁盘上读到数据缓冲区中。我们可以想象得到,SQL Server在执行物理读时比执行逻辑读需要更多的服务器资源。因此,在理想情况下,我们应当尽量避免物理读操作。下面的这一部分听起来让人容易感到糊涂 了。在对查询的性能进行调节时,可以忽略物理读而只专注于逻辑读。你一定会纳闷儿,刚才不是还说物理读比逻辑读需要更多的服务器资源吗?情况确实是这样, SQL Server在执行查询时所需要的物理读次数不可能通过性能调节而减少的。减少物理读的次数是DBA的一项重要工作,但它涉及到整个服务器性能的调节,而 不仅仅是查询性能的调节。在进行查询性能调节时,我们不能控制数据缓冲区的大小或服务器的忙碌程度以及完成查询所需要的数据是在数据缓冲区中还是在磁盘 上,唯一我们能够控制的数据是得到查询结果所需要执行的逻辑读的次数。

 

因此,在查询性能的调节中,我们可以心安理得地不理会SET STATISTICS IO命令提供的Physical Read的值。(减少物理读次数、加快SQL Server运行速度的一种方式是确保服务器的物理内存足够多。)
  相关解决方案