Select * faster than select column
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)
I'm writing a recursive CTE SQL statement to pull items from a tree. The query works fine. When I select a specific column(s) the query executes in ~300ms. However when I use select *
or p.*
, the query executes under 100ms. This is the exact opposite of what I would expect. I have checked indexes, statistics, and both quer开发者_运维技巧ies seem to generate the same execution plan. I'm stumped on this one.
Update
I've been running this query all day with consistent results. I've attempted to disable caching by using OPTION (RECOMPILE). I've just been using the "Wait time on server replies" in sql manager to measure the query execution (is that bad?) Here is what happens when I use SET STATISTICS TIME ON.
p.oid => SQL Server Execution Times: CPU time = 203 ms, elapsed time = 270 ms. "Wait time" = 195ms
p.* => SQL Server Execution Times: CPU time = 469 ms, elapsed time = 1015 ms. "Wait time" = 21ms
I have the other stats if they are needed. Is the client wait time time the wrong way to measure these things?
It turns out that using the MS SQL manager to measure execution times is very unreliable. Thanks to Martin using SET STATISTICS TIME ON gave me more accurate results.
Doing SELECT * is actually much slower than doing a column select when measured correctly
According to this answer
'Wait time on server replies' is the time between the last request packet left the client and the very first response packet returned from the server.
On my machine it seems that it waits until it has somewhere around 4000 bytes to return before sending the first packet from the test below.
When *
is selected fewer rows need to be processed to fill this buffer.
SELECT 'A'
WAITFOR delay '00:00:02'
Gives
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
And
SELECT REPLICATE('A',4000)
WAITFOR delay '00:00:02'
Gives
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
精彩评论