选择*比选择列快

时间:2011-03-25 23:26:09

标签: sql tsql

WITH Categories (child_oid, Level) AS ( 
   SELECT h.child_oid, 
          0 AS Level 
     FROM Memx_productcatalog.dbo.ME_CatalogHierarchy AS h 
     JOIN dbo.[ME_CatalogProducts] c on h.oid = c.oid 
    WHERE c.CategoryName = 'Root' 
   UNION ALL 
   SELECT h.child_oid, 
          Level + 1 
     FROM dbo.ME_CatalogHierarchy AS h 
     JOIN Categories AS p ON p.child_oid = h.oid ) --End CTE Recursive
SELECT p.oid --problem here
  FROM dbo.ME_CatalogProducts as p
 WHERE p.oid IN (SELECT child_oid 
                   FROM Categories)

我正在编写一个递归CTE SQL语句来从树中提取项目。查询工作正常。当我选择特定列时,查询在~300ms内执行。但是,当我使用select *p.*时,查询将在100毫秒内执行。这与我的期望完全相反。我检查了索引,统计信息,并且两个查询似乎都生成了相同的执行计划。我很难过这个。

更新

我整天都在运行此查询并获得一致的结果。我试图通过使用OPTION(RECOMPILE)来禁用缓存。我刚刚在sql管理器中使用“服务器回复上的等待时间”来测量查询执行(这是不是很糟糕?)以下是使用SET STATISTICS TIME ON时会发生的情况。

p.oid => SQL Server执行时间:    CPU时间= 203毫秒,经过时间= 270毫秒。 “等待时间”= 195ms

p。* => SQL Server执行时间:    CPU时间= 469 ms,经过时间= 1015 ms。 “等待时间”= 21毫秒

如果需要,我还有其他统计数据。客户端等待时间是否以错误的方式来衡量这些事情?

2 个答案:

答案 0 :(得分:4)

事实证明,使用MS SQL管理器来测量执行时间是非常不可靠的。 感谢Martin使用SET STATISTICS TIME ON给了我更准确的结果。

执行SELECT *实际上要比正确测量时的列选择慢得多

答案 1 :(得分:0)

根据this answer

'服务器回复上的等待时间'是最后一个请求数据包离开客户端和从服务器返回的第一个响应数据包之间的时间。

在我的机器上,它似乎等到它返回大约4000字节的某个地方才能从下面的测试中发送第一个数据包。

选择*时,需要处理更少的行来填充此缓冲区。

SELECT 'A'
WAITFOR delay '00:00:02' 

给出

  TDS packets sent from client        1
  TDS packets received from server    1
  Bytes sent from client              180        
  Bytes received from server          610    
  Client processing time              8    
  Total execution time                2008    
  Wait time on server replies         2000

SELECT REPLICATE('A',4000)
WAITFOR delay '00:00:02' 

给出

  Number of server roundtrips         1
  TDS packets sent from client        1
  TDS packets received from server    2
  Bytes sent from client              222
  Bytes received from server          4619
  Client processing time              1885
  Total execution time                1914
  Wait time on server replies         29