2011-03-25 79 views
2
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.*时,查询在100ms以下执行。这与我所期望的完全相反。我检查了索引,统计数据,并且这两个查询似乎都会生成相同的执行计划。我被困在这一个。选择*比选择列更快

更新

我整天一直运行此查询结果一致。我试图通过使用OPTION(RECOMPILE)来禁用缓存。我刚刚在SQL管理器中使用了“等待服务器回复时间”来衡量查询执行情况(这是否不好?)以下是我使用SET STATISTICS TIME ON时发生的情况。

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

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

我有其他统计资料,如果他们需要。客户是否等待时间错误地衡量这些事情?

+6

多少测试已经做了什么?你有没有尝试颠倒测试的顺序(如果缓存正在播放一部分)? “SET STATISTICS IO ON”和“SET STATISTICS TIME ON”对两者都适用? – 2011-03-25 23:29:23

+0

也许我有一个有缺陷的理解,但我期望'*'会更快。毕竟,数据库不需要执行任何投影。 – syrion 2011-03-25 23:42:32

+2

@syrion:你不认为限制返回的数据会更快吗? – 2011-03-25 23:44:41

回答

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 
4

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

执行SELECT *其实比做正确的测量