Я порівнюю два запити в SQL Server 2012. Мета полягає у використанні всієї відповідної інформації, доступної в оптимізаторі запитів, при виборі найкращого запиту. Обидва запити дають однакові результати; максимальна кількість замовлень для всіх клієнтів.
Очищення пулу буфера було виконано перед виконанням кожного запиту за допомогою FREEPROCCACHE та DROPCLEANBUFFERS
Використовуючи інформацію, надану нижче, який запит є кращим вибором?
-- Query 1 - return the maximum order id for a customer
SELECT orderid, custid
FROM Sales.Orders AS O1
WHERE orderid = (SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = O1.custid);
-- Query 2 - return the maximum order id for a customer
SELECT MAX(orderid), custid
FROM Sales.Orders AS O1
group by custid
order by custid
ЧАС СТАТИСТИКИ
Запит 1 СТАТИСТИКА ЧАС: час процесора = 0 мс, минулий час = 24 мс
Запит 2 СТАТИСТИКА ВРЕМЯ: час процесора = 0 мс, минулий час = 23 мс
СТАТИСТИКА ІО
Запит 1 СТАТИСТИКА IO: Таблиця "Замовлення". Кількість сканувань 1, логічне зчитування 5, фізичне зчитування 2, зчитування вперед-зчитування 0, логічне зчитування лобі 0, лобічне фізичне зчитування 0, лобічне зчитування попереднє зчитування 0.
Запит 2 СТАТИСТИКА IO: Таблиця "Замовлення". Кількість сканувань 1, логічне зчитування 4, фізичне зчитування 1, зчитування вперед-зчитування 8, логічне зчитування лобі 0, лобічне фізичне зчитування 0, лобічне зчитування вперед-0.
Плани виконання
SELECT властивості Запит 1
SELECT властивості Запит 2
Висновки:
Запит 1
- Вартість партії 48%
- Логічні читання 5
- Фізичні читання 2
- Читання вперед: 0
- Час процесора: 0 мс
- Час минув 24 мс
- Орієнтовна вартість піддерева: 0,0050276
- КомпіляціяCPU: 2
- Пам'ять компіляції: 384
- Час компіляції: 2
Запит 2
- Вартість партії - 52%
- Логічні читання 4
- Фізичні читання 1
- Читання наперед: 8
- Час процесора 0
- Час минув 23 мс
- Орієнтовна вартість піддерева: 0,0054782
- СкладітьCPU: 0
- Пам'ять компіляції: 192
- Час компіляції: 0
Особисто, навіть якщо запит 2 має більш високу пакетну вартість відповідно до графічного плану, я вважаю його більш ефективним, ніж запит 1. Це тому, що запит 2 вимагає менш логічного читання, має трохи менший минулий час, значення збирання, збірника та компіляції є нижній. попередні читання - 8 для запиту 2 та 0 для запиту 1.
Оновлення 12:03
Визначення кластерного індексу
ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[orderid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Індекс без кластера idx_nc_custid
CREATE NONCLUSTERED INDEX [idx_nc_custid] ON [Sales].[Orders]
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO