Я сравниваю два запроса в 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 STATISTICS TIME: время процессора = 0 мс, прошедшее время = 24 мс
Запрос 2 STATISTICS TIME: время процессора = 0 мс, прошедшее время = 23 мс
СТАТИСТИКА IO
Запрос 1 STATISTICS IO: Таблица «Заказы». Сканирование 1, логическое чтение 5, физическое чтение 2, чтение с опережением 0, логическое чтение с бита 0, физическое чтение с бита 0, чтение с опережением чтения 0.
Запрос 2 STATISTICS IO: Таблица «Заказы». Сканирование 1, логическое чтение 4, физическое чтение 1, чтение с опережением 8, логическое чтение с бита 0, физическое чтение с бита 0, чтение с опережением чтения 0.
Планы выполнения
ВЫБЕРИТЕ свойства Query 1
ВЫБЕРИТЕ свойства Query 2
Выводы:
Запрос 1
- Пакетная стоимость 48%
- Логические чтения 5
- Физические чтения 2
- Чтение впереди: 0
- Время процессора: 0 мс
- Прошедшее время 24 мс
- Ориентировочная стоимость поддерева: 0,0050276
- CompileCPU: 2
- CompileMemory: 384
- CompileTime: 2
Запрос 2
- Пакетная стоимость 52%
- Логические чтения 4
- Физические Чтения 1
- Чтение вперед: 8
- Процессорное время 0
- Прошедшее время 23мс
- Ориентировочная стоимость поддерева: 0,0054782
- CompileCPU: 0
- CompileMemory: 192
- CompileTime: 0
Лично, хотя Query 2 имеет более высокую стоимость пакета в соответствии с графическим планом, я думаю, что он более эффективен, чем Query 1. Это потому, что запрос 2 требует меньше логических чтений, имеет немного меньшее время, затрачиваемое на значения compilecpu, compilememory и compiletime. понизит. чтение с опережением - 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