简体   繁体   English

SQL Server,如何比较简单查询的速度

[英]SQL Server , How to compare speeds of simple Queries

I have a big query and I am tring to improve it part by part, however due to the caching mechanism, and simplicity of t-sql codes, I don't have a reliable environment for testing the speeds. 我有一个很大的查询,并且我想部分地加以改进,但是由于缓存机制和t-sql代码的简单性,我没有一个可靠的环境来测试速度。 The queries that I am tring to improve about speeds are all last about 1 or 2 seconds, so I can't see the difference clearly. 我正在努力提高速度的查询全部持续大约1或2秒,因此我看不出有什么区别。 And creating dummy data for each comparision takes too much time. 为每个比较创建伪数据需要太多时间。 What do you suggest me to do ? 你建议我做什么? I am using my company database, so removing cache everytime can be harmful I guess. 我正在使用公司数据库,因此每次删除缓存都可能有害。

Edit: After reading all the comments, I made some tring and I got some idea. 编辑:阅读所有评论后,我做了一些调整,然后有了一些想法。 But looking all those values in statistics does it exactly what I want ? 但是,查看统计信息中的所有这些值是否正是我想要的?

Here are the problems that I faced: 这是我面临的问题:

Execution Plan: First I run some queries and looked at Execution Plan, at the top - Query cost (Relative to the batch) I couldn't get a value other than 0.00%. 执行计划:首先,我运行一些查询,并查看执行计划,位于顶部-查询成本(相对于批次),除0.00%外,我没有其他值。 Even my query lasts more than 1 minutes. 甚至我的查询也持续超过1分钟。 Only thing I get is 0.00%. 我唯一得到的是0.00%。 And under the graphs, all the values are 0% 在图表下,所有值均为0%

DB Statistics . 数据库统计 Now I am testing two queries. 现在,我正在测试两个查询。 One of them is 其中之一是

SELECT * FROM My_TABLE /* WHERE 选择*从My_TABLE / *在哪里
my_primarykey LIKE '%ht_atk%' */ my_primarykey LIKE'%ht_atk%'* /

And the second one is the comment free version. 第二个是免费评论版本。

SELECT * FROM My_TABLE WHERE SELECT * FROM My_TABLE在哪里
my_primarykey LIKE '%ht_atk%' my_primarykey类似'%ht_atk%'

Here my results from DB Statistics, first query:. 这里是我从DB Statistics的结果,第一个查询:。

Application Profile Statistics      
  Timer resolution (milliseconds)   0   0
  Number of INSERT, UPDATE, DELETE statements   0   0
  Rows effected by INSERT, UPDATE, DELETE statements    0   0
  Number of SELECT statements   2   2
  Rows effected by SELECT statements    16387   15748,4
  Number of user transactions   7   6,93182
  Average fetch time    0   0
  Cumulative fetch time 0   0
  Number of fetches 0   0
  Number of open statement handles  0   0
  Max number of opened statement handles    0   0
  Cumulative number of statement handles    0   0

Network Statistics      
  Number of server roundtrips   3   3
  Number of TDS packets sent    3   3
  Number of TDS packets received    252 242,545
  Number of bytes sent  868 861,091
  Number of bytes received  1,01917e+006    981160

Time Statistics     
  Cumulative client processing time 0   0,204545
  Cumulative wait time on server replies    25  10,0455

Second Query: 第二个查询:

Application Profile Statistics      
  Timer resolution (milliseconds)   0   0
  Number of INSERT, UPDATE, DELETE statements   0   0
  Rows effected by INSERT, UPDATE, DELETE statements    0   0
  Number of SELECT statements   2   2
  Rows effected by SELECT statements    14982   15731,3
  Number of user transactions   5   6,88889
  Average fetch time    0   0
  Cumulative fetch time 0   0
  Number of fetches 0   0
  Number of open statement handles  0   0
  Max number of opened statement handles    0   0
  Cumulative number of statement handles    0   0

Network Statistics      
  Number of server roundtrips   3   3
  Number of TDS packets sent    3   3
  Number of TDS packets received    230 242,267
  Number of bytes sent  752 858,667
  Number of bytes received  932387  980076

Time Statistics     
  Cumulative client processing time 1   0,222222
  Cumulative wait time on server replies    8   10

Every single time I execute, the values are randomly changing and I am not able to catch a good view about which query is faster. 每执行一次,值就会随机变化,而且我无法很好地了解哪个查询更快。

Lastly when I do that: 最后,当我这样做时:

SET STATISTICS TIME ON SET STATISTICS IO ON 设置统计信息时间开启设置统计信息时间开启

For both queries, the results are same. 对于这两个查询,结果都是相同的。

Table 'my_TABLE'. 表“ my_TABLE”。 Scan count 1, logical reads 682, physical reads 0, read-ahead reads 0. 扫描计数1,逻辑读682,物理读0,预读读0。

So again I couldn't make a comparision between the two queries. 因此,我无法在两个查询之间进行比较。 how to interpret the results ? 结果如何解释? Am I looking to the wrong place. 我在找错地方了吗? How can I compare those two simple queries above ? 如何比较上面的两个简单查询?

Use the query analyzer to find out the expensive parts of your query (this depends on DB statistics, so use representative data). 使用查询分析器找出查询中昂贵的部分(这取决于数据库统计信息,因此请使用代表性数据)。

This will let you zero in on the parts you should optimize. 这样您就可以将要优化的零件归零。

Trying to time things with a stopwatch or looking at the time it takes for the results to return to SSMS will be guesswork at best. 尝试使用秒表计时或查看结果返回SSMS所需的时间充其量只是猜测。

Run the set statistics time on and set statistics io on then run the big query in text mode. 运行set statistics time onset statistics io on然后以文本模式运行大查询。 You can put some prints after each part of the query you want to optimize. 您可以在要优化的查询的每个部分之后放置一些打印件。

You will get lines like: 您将获得如下代码:

Table 'Table'. Scan count 1, logical reads 10, physical reads 0, read-ahead reads 0, lob    logical reads 387, lob physical reads 0, lob read-ahead reads 0.

Try to put some data in the tables and check the Scan Count and logical reads for big numbers. 尝试在表中放入一些数据,然后检查“扫描计数”和逻辑读取是否有大数字。

You can also check the Actual Execution Plan and search for any clustered index scan. 您还可以检查实际执行计划并搜索任何聚集索引扫描。 This may indicate that there is a missing index in some table. 这可能表明某个表中缺少索引。

In query analyzer go to Query > Include Actual Execution Plan and Query > Include Client Statistics. 在查询分析器中,转到查询>包括实际执行计划,然后转到查询>包括客户端统计信息。

Use the Execution Plan to identify the most costly parts of your query. 使用执行计划来确定查询中最昂贵的部分。 When you mouse over or click any of the nodes it will show you a whole group of statistics. 当您将鼠标悬停或单击任何节点时,它将显示一组完整的统计信息。 Try to see if you can rework a join or filter to reduce the number of rows returned. 尝试查看是否可以重新处理联接或过滤器以减少返回的行数。

Use Client Statistics to compare two queries. 使用客户端统计信息比较两个查询。 Each time you run your query it will add a new column to the client stats page. 每次运行查询时,都会在客户端统计信息页面中添加新列。 You want to look at the bottom group: Time Statistics. 您要查看底部组:时间统计。

I know some of these are obvious, but here are a few general tips for reducing your load: -Return only the columns you need. 我知道其中一些是显而易见的,但是这里有一些减少负载的一般技巧:-仅返回所需的列。 Sometimes people return all columns, or some identifier columns that they use for coding but the end user doesn't need. 有时,人们返回所有列或用于编码的某些标识符列,但最终用户不需要。 -For each table - reduce the number of rows returned. -对于每个表-减少返回的行数。 -Try not to use temp tables when you don't have to. -尽量不要使用临时表。 This causes a 'double dip', or querying the same very large table multiple times. 这将导致“两次探底”,或多次查询同一张非常大的表。

Good way is too see execution plain. 好的方法也是看执行。 It tell alot about how query will execute and what is taking most of the time. 它告诉了很多关于查询将如何执行以及大部分时间的信息。 You can even decide to create indexes on that bases. 您甚至可以决定在此基础上创建索引。 Its very usefull specially of large queries. 它对大型查询特别有用。 SQLServer most of the time find best possible way to execute query but you can improve that by providing it with index on field that are used in WHERE and JOIN statements. SQLServer在大多数时候都找到了执行查询的最佳方法,但是您可以通过在WHERE和JOIN语句中使用的字段上提供索引来改进它。 If you cannot read execution plain which is like graph with estimated cost and timing you can read in detail about it from MSDN. 如果您无法阅读简单的执行方式(类似于带有估计成本和时序的图形),则可以从MSDN中详细了解它。

as @affan said, the best way is to use the information given by the execution plan. 正如@affan所说,最好的方法是使用执行计划提供的信息。 but you can always set up a simple counter with code like 但您始终可以使用以下代码设置一个简单的计数器

IF @debug > 0 BEGIN
    DECLARE @now DATETIME;
    SET @now = CURRENT_TIMESTAMP;
END

and

IF @debug > 0 BEGIN
    SELECT DATEDIFF(ms,@now,CURRENT_TIMESTAMP)/1000.0 AS Runtime;
END

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM