Выбрать * быстрее, чем выбрать столбец - PullRequest
2 голосов
/ 26 марта 2011
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)

Я пишу рекурсивный SQL-оператор CTE для извлечения элементов из дерева.Запрос работает нормально.Когда я выбираю определенный столбец (столбцы), запрос выполняется за ~ 300 мс.Однако когда я использую select * или p.*, запрос выполняется менее 100 мс.Это полная противоположность того, что я ожидал.Я проверил индексы, статистику, и оба запроса, кажется, генерируют один и тот же план выполнения.Я поставлен в тупик.

Обновление

Я выполнял этот запрос весь день с единообразными результатами.Я попытался отключить кэширование с помощью OPTION (RECOMPILE).Я только что использовал «Время ожидания ответов сервера» в диспетчере SQL для измерения выполнения запроса (это плохо?) Вот что происходит, когда я использую SET STATISTICS TIME ON.

p.oid => Время выполнения SQL Server: время ЦП = 203 мс, прошедшее время = 270 мс.«Время ожидания» = 195 мс

стр. * => Время выполнения SQL Server: время ЦП = 469 мс, истекшее время = 1015 мс.«Время ожидания» = 21мс

У меня есть другие характеристики, если они нужны.Является ли время ожидания клиента неправильным способом измерения этих вещей?

Ответы [ 2 ]

4 голосов
/ 26 марта 2011

Оказывается, что использование менеджера MS SQL для измерения времени выполнения очень ненадежно.Благодаря Мартину использование SET STATISTICS TIME ON дало мне более точные результаты.

Выполнение SELECT * на самом деле намного медленнее, чем выбор столбца при правильном измерении

0 голосов
/ 26 марта 2011

Согласно этому ответу

«Время ожидания ответов сервера» - это время между последним пакетом запроса, оставленным клиентом, и самым первым пакетом ответа, возвращенным с сервера.

На моей машине кажется, что она ожидает возврата примерно 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...