В этой статье мы рассмотрим концепцию фильтрованных статистик и их влияние на оценку кардинальности в SQL Server. Фильтрованные статистики – это новая функция, введенная в фреймворк оценки кардинальности SQL Server 2014. Она позволяет создавать статистику “на лету” на основе определенных условий фильтрации для улучшения производительности запросов.
Прежде чем мы углубимся в детали, важно отметить, что использование фильтрованных статистик не задокументировано и не поддерживается Microsoft. Они должны использоваться только в образовательных и экспериментальных целях в тестовой среде. Внедрение фильтрованных статистик в производственную систему может негативно сказаться на общей производительности сервера.
Рассмотрим пример, используя базу данных AdventureWorks2012 с уровнем совместимости SQL Server 2014. У нас есть запрос, который объединяет таблицы Sales.Customer и Person.Person, фильтруя результаты по TerritoryID:
SELECT COUNT(*)
FROM Sales.Customer c
JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
WHERE c.TerritoryID = 3
Оценочное количество строк, возвращаемых объединением, составляет 127,331, тогда как фактическое количество строк равно 69. Это расхождение происходит потому, что фильтр на столбце TerritoryID использует гистограмму столбца объединения PersonID в процессе оценки.
Чтобы решить эту проблему, мы можем вручную создать фильтрованные статистики, повторно выполнить запрос, а затем удалить фильтрованные статистики:
CREATE STATISTICS s_PersonID_TerritoryID_Equals3 ON Sales.Customer (PersonID) WHERE TerritoryID = 3;
DBCC FREEPROCCACHE;
SELECT COUNT(*)
FROM Sales.Customer c
JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
WHERE c.TerritoryID = 3;
DROP STATISTICS Sales.Customer.s_PersonID_TerritoryID_Equals3;
После создания фильтрованных статистик оценка теперь соответствует фактическому количеству строк, которое равно 69. Это демонстрирует эффективность использования фильтрованных статистик для улучшения оценки кардинальности.
Интересно, что фреймворк оценки кардинальности в SQL Server 2014 имеет возможность выполнять эту операцию “на лету”, когда это считается целесообразным. Чтобы принудительно использовать эту модельную вариацию, мы можем использовать не задокументированный флаг трассировки 9483. Кроме того, флаг трассировки 2363 можно использовать для просмотра диагностического вывода, а Profiler (или xEvents) можно использовать для мониторинга соответствующих событий.
SELECT COUNT(*)
FROM Sales.Customer c
JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
WHERE c.TerritoryID = 3
OPTION (RECOMPILE, QUERYTRACEON 3604, QUERYTRACEON 2363, QUERYTRACEON 9483);
Включив эти флаги трассировки и запустив запрос, мы можем наблюдать создание фильтрованных статистик “на лету” перед построением плана запроса. Эти статистики не сохраняются в представлении sys.stats и создаются только во время оптимизации запроса.
Фильтрованные статистики предлагают любопытную модельную вариацию в фреймворке оценки кардинальности. Хотя создание статистики для каждой оптимизации запроса может потреблять много ресурсов, в некоторых сценариях и особых случаях оно может оказаться полезным. Microsoft реализовала его как модельную вариацию для решения конкретных проблем оценки кардинальности.
Это все на сегодня. В следующей статье мы обсудим другие изменения в новом фреймворке оценки кардинальности. Следите за обновлениями!