运行多个连续语句时出现意外的查询统计信息

时间:2019-05-03 09:53:50

标签: sql-server performance database-tuning code-statistics

使用SQL Server 2016及更高版本

我目前正在评估两种显示搜索结果的方法。显示与“条件”匹配的所有“产品”。

我一直在研究将符合条件的ID列表存储在临时表中的优点,然后再加入我的主要产品,而动态创建的会话视图将ID编码为值。

下面的脚本示例。我已经省略了主要产品表本身,因为它只是一个大的平板,但确实包含公司专有的详细信息。代码本身不是问题,而是它生成的统计信息。

SET STATISTICS IO, TIME OFF;

DROP TABLE IF EXISTS dba.Temp;
DROP VIEW IF EXISTS dba.Test1;
DROP VIEW IF EXISTS dba.Test2;

CREATE TABLE dba.Temp (ProductID INT);

INSERT INTO dba.Temp (ProductID)
SELECT  TOP 1000
        ProductID
  FROM  dbo.Products
 ORDER BY NEWID();
GO

CREATE VIEW dba.Test1
AS
    SELECT  P.*
      FROM  Products P
      JOIN  dba.Temp T ON T.ProductID = P.ProductID;
GO

DECLARE @strSQL AS NVARCHAR(MAX);

SET @strSQL = N'';

SELECT  @strSQL = @strSQL + N',(' + CAST(ProductID AS NVARCHAR(MAX)) + N')'
  FROM  dba.Temp;

SET @strSQL = STUFF(@strSQL, 1, 1, ('CREATE VIEW dba.Test2 AS SELECT P.* FROM Products P JOIN (VALUES ')) + N') T (ProductID) ON T.ProductID = P.ProductID';

EXEC sp_executesql @stmt = @strSQL;
GO

SET STATISTICS IO, TIME ON;

PRINT '------------------------------ Test 1'; 
SELECT * FROM dba.Test1; 
PRINT '------------------------------ Test 2'; 
SELECT * FROM dba.Test2; 
PRINT '------------------------------ End';

SET STATISTICS IO, TIME OFF;

我发现数据集上的两个选项之间几乎没有什么区别,但是根据我的测试方式,我会得到一些非常奇怪的结果。

如果我仅从测试1中读取数据,则我收到的统计信息与以下类似,但经过时间的波动很小-我不是服务器上的唯一用户。

SQL Server parse and compile time: 
   CPU time = 8 ms, elapsed time = 8 ms.
------------------------------ Test 1

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3071, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Temp'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 47 ms,  elapsed time = 56 ms.

运行测试2,仅在IO较低的情况下我收到了非常相似的结果(预期不会从临时表中读取)

SQL Server parse and compile time: 
   CPU time = 46 ms, elapsed time = 46 ms.
------------------------------ Test 2

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3071, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 47 ms,  elapsed time = 57 ms.

无论如何同时运行这两个测试,我发现在第二次运行查询时结果总是慢得多。

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
------------------------------ Test 1

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3063, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Temp'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 47 ms,  elapsed time = 56 ms.
------------------------------ Test 2

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1000 rows affected)
Table 'Products'. Scan count 0, logical reads 3063, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 62 ms,  elapsed time = 200 ms.
------------------------------ End

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

第二个查询的偏斜结果是否有逻辑原因?是第一个查询正在创建影响第二个查询的负载吗?我想知道我是否缺少某些东西或有基本的误解。这就是我通常会调整流程,强调IO,关注时间的方式。如果我需要调整调整方法,那么我们将不胜感激。

0 个答案:

没有答案