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毫秒
如果需要,我还有其他统计数据。客户端等待时间是否以错误的方式来衡量这些事情?
答案 0 :(得分:4)
事实证明,使用MS SQL管理器来测量执行时间是非常不可靠的。 感谢Martin使用SET STATISTICS TIME ON给了我更准确的结果。
执行SELECT *实际上要比正确测量时的列选择慢得多
答案 1 :(得分:0)
'服务器回复上的等待时间'是最后一个请求数据包离开客户端和从服务器返回的第一个响应数据包之间的时间。
在我的机器上,它似乎等到它返回大约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