Ответ 1
Во-первых, вы должны убедиться, что сортировка на самом деле является узким местом производительности. Продолжительность сортировки будет зависеть от количества отсортированных элементов, а количество магазинов для определенного родительского хранилища, вероятно, будет небольшим. (Предполагается, что оператор сортировки применяется после применения предложения where).
Ive слышал, что оператор Sort указывает на плохой дизайн в запросе, поскольку сортировка может быть сделана преждевременно через индекс
Это чрезмерное обобщение. Часто оператор сортировки может тривиально перемещаться в индекс, и, если извлекаются только первые пары строк результирующего набора, может существенно снизить стоимость запроса, поскольку базе данных больше не нужно извлекать все соответствующие строки (и сортировать их все), чтобы найти первые, но может читать записи в порядке набора результатов и останавливаться, как только будет найдено достаточно записей.
В вашем случае вы, кажется, извлекаете весь набор результатов, поэтому сортировка вряд ли сделает вещи намного хуже (если набор результатов не огромен). Кроме того, в вашем случае не может быть тривиально создавать полезный отсортированный индекс, потому что предложение where содержит a или.
Теперь, если вы все еще хотите избавиться от этого sort-оператора, вы можете попробовать:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] in (0, 1)
ORDER BY [Phone]
В качестве альтернативы вы можете попробовать следующий индекс:
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Phone], [Type])
чтобы попытаться заставить оптимизатор запросов выполнить проверку диапазона индекса только на ParentStoreId
, а затем проверить все соответствующие строки в индексе, выводя их, если Type
соответствует. Однако это, скорее всего, вызовет больше дискового ввода-вывода и, следовательно, замедлит ваш запрос, а не ускорит его.
Изменить. В качестве последнего средства вы можете использовать
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] = 0
ORDER BY [Phone]
UNION ALL
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] = 1
ORDER BY [Phone]
с
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])
и сортировать два списка на сервере приложений, где вы можете объединить (как в сортировке слияния) прессованные списки, тем самым избегая полного сортировки. Но это действительно микро-оптимизация, которая, хотя и ускоряет сортировку на порядок, вряд ли повлияет на общее время выполнения запроса, так как я ожидаю, что узким местом станет сетевое и дисковое ввода/особенно в свете того факта, что диск будет делать много произвольного доступа, поскольку индекс не кластеризуется.