Сегодня ведущий администратор базы данных на работе сказал, что я не должен использовать ITVF, чтобы полностью обернуть представление, но из моих элементарных тестов я остаюсь скептиком.Кажется, что SQL Server просто сортирует те столбцы, которые ему действительно нужны (на основе того, что запрашивается из функции) во время запроса.Я говорю это, потому что я вижу очень похожие времена выполнения между двумя примерами ниже.
uf_GetCustomersByCity_A
В этом примере я создаю ITVF, который выполняет SELECT *
,возвращение отфильтрованного CustomerView
.
CREATE FUNCTION [dbo].[uf_GetCustomersByCity_A] (@idCity INT)
RETURNS TABLE
AS RETURN
SELECT CustView.*
FROM [dbo].[CustomerView] CustView
WHERE CustView.idCity = @idCity
GO
uf_GetCustomersByCity_B
CREATE FUNCTION [dbo].[uf_GetCustomersByCity_B] (@idCity INT)
RETURNS TABLE
AS RETURN
SELECT CustView.idCustomer
, CustView.cFullName
, CustView.cCityName
, CustView.fBalance
FROM [dbo].[CustomerView] CustView
WHERE CustView.idCity = @idCity
GO
Мой вопрос заключается в том, является ли это действительным наблюдением, или это просто сторонаэффект отладки в течение многих часов (при условии, что SQL Server оптимизируется с использованием).Было очень полезно предлагать в представлении все, что нужно, вместо указания каждого столбца специально в ITVF.
Любительские тесты
Так что оба работают довольно хорошо, с выходом ~500 000 строк в течение 4-5 секунд (примечание: существуют сложные предложения, дающие долгое время выполнения, и эти примеры вряд ли иллюстрируют цель здесь).В представлении есть что-то вроде 70 или 80 столбцов, многие из которых отформатированы или обрабатываются внутри строки.
-- Around 500k rows in ~3-4 seconds:
SELECT idCustomer, cCityName
FROM [dbo].[uf_GetCustomersByCity_A](93)
-- Around 500k rows, again ~3-4 seconds:
SELECT idCustomer, cCityName
FROM [dbo].[uf_GetCustomersByCity_B](93)
Такая же производительность в блоке разработчика, но в настоящее время его никто не использует.Предположим, что cFullName
- это объединение cGivenName
и cFamilyName
, тогда как cCityName
возвращается в точности как сохранено.Добавление cCityName
к запросу имеет значительно меньшее влияние, чем cFullName
, что заставляет меня поверить, что это не время доставки в SSMS, которое я замечаю.
-- Around 500k rows, ~6 seconds:
SELECT idCustomer, cFullName
FROM [dbo].[uf_GetCustomersByCity_A](93)
-- Around 500k rows, ~6 seconds:
SELECT idCustomer, cFullName
FROM [dbo].[uf_GetCustomersByCity_B](93)
Я думаю, что если SELECT *
имеет значение в рамках ITVF, тогда он будет тратить кучу времени на определение значений для столбцов, которые он не использует.Из быстрых тестов, которые я разработал, я не вижу особой разницы, когда оборачиваю весь вид с помощью SELECT *
, вместо того, чтобы указывать столбцы по одному, восстанавливая структуру представления по существу.Моя догадка действительна здесь?