Поделиться через


Проблема с производительностью при запросе представлений между связанными серверами

Применяется к: SQL Server

Симптомы

Выполнение запроса к представлениям на связанном сервере занимает больше времени, чем выполнение того же запроса непосредственно в базовой таблице на связанном сервере.

Причина

Выполнение запроса к представлению и базовой таблице приводит к другому поведению из-за оценки кратности данных, которая используется для вычисления ожидаемого количества возвращаемых строк. Число представлений запросов имеет постоянное значение 10 000, а число базовых таблиц является производным от статистической информации.

Оценка кратности для базовой таблицы, запрашиваемой связанными серверами

Поставщик Microsoft OLE DB (SQLOLEDB) (больше не поддерживается) или Microsoft® OLE DB Driver 18 for SQL Server® (MSOLEDBSQL) поддерживают статистику распределения в базовых таблицах. SQL Server может использовать статистику и гистограмму над связанными серверами так же, как и любой обычный запрос. Например, если создать связанный сервер с именем LS1 с AdventureWorks2019 базой данных с Sales.SalesOrderDetail таблицей, следующие запросы могут использовать статистическую гистограмму:

SELECT * FROM LS1.AdventureWorks2019.Sales.SalesOrderDetail;
SELECT * FROM LS1.AdventureWorks2019.Sales.SalesOrderDetail WHERE SalesOrderID=43659;

В следующих графических планах запросов показано предполагаемое количество строк, возвращаемых для каждого удаленного запроса.

Снимок экрана: запрос на таблицу на связанном сервере.

Оценка кратности для представлений, запрашиваемых связанными серверами

Связанные серверные запросы к представлениям не используют оценку кратности на основе статистики. Оценка кратности для представления является константным значением 10 000. Следующий тест иллюстрирует следующее:

  1. Создайте представление с именем dbo.View1 , которое ссылается Sales.SalesOrderDetail на таблицу из AdventureWorks2019 базы данных связанного сервера LS1.

    USE AdventureWorks2019;
    GO
    CREATE VIEW [dbo].[view1]
    AS
    SELECT * FROM Sales.SalesOrderDetail;
    
  2. Удаленно запрашивать представление.

    SELECT * FROM LS1.AdventureWorks2019.dbo.view1;
    
  3. Оценка кратности запроса показывает ровно 10 000 строк.

    Снимок экрана: запрос для просмотра на связанном сервере.

Оценка кратности для представления, запрашиваемого связанными серверами с предложением WHERE

При выполнении запроса с WHERE предложением для представлений на связанном сервере оценка кратности по представлениям также является константным значением. Однако значение зависит от уровня совместимости базы данных.

Примечание.

Значение оценки кратности не будет влиять на уровень совместимости базы данных, в которой определено представление.

  • Для уровня совместимости базы данных 120 или выше (новая версия оценки кратности) оценка кратности составляет 100.
  • Для уровня совместимости базы данных 110 или более низкого (устаревшего оценки кратности) оценка кратности составляет 1000.

Пример см. в следующих запросах:

SELECT * FROM LS1.AdventureWorks2019.dbo.view1
WHERE SalesOrderID=43659 
    OPTION (USE HINT ('FORCE_DEFAULT_CARDINALITY_ESTIMATION'));
GO
SELECT * FROM LS1.AdventureWorks2019.dbo.view1 
WHERE SalesOrderID=43659
OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'));

Пример см. в следующей оценке кратности запросов.

Снимок экрана: запрос на просмотр CE на связанном сервере.

Решение

В большинстве случаев никаких действий не требуется, так как большинство рабочих нагрузок приложений не будут влиять на оценку кратности представлений при запросе с связанных серверов. Если рабочая нагрузка затронута, используйте один из следующих методов:

  • Обновите и измените представление в виде индексированного представления. Индексированные представления имеют по крайней мере один индекс с соответствующей статистикой. См. следующие запросы для создания и запроса индексированного представления.

    Примечание.

    Этот метод предоставляет фактическую статистику, представляющую базовые данные.

    --Set the options to support indexed views.
    SET NUMERIC_ROUNDABORT OFF;
    SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
       QUOTED_IDENTIFIER, ANSI_NULLS ON;
    GO
    IF OBJECT_ID ('Sales.vOrderDetails1', 'view') IS NOT NULL
       DROP VIEW Sales.vOrderDetails1;
    GO
    --Create view with schemabinding
    CREATE VIEW Sales.vOrderDetails1
       WITH SCHEMABINDING
       AS  
          SELECT SalesOrderID, 
           SalesOrderDetailID, 
           CarrierTrackingNumber, 
           OrderQty, 
           ProductID,
           UnitPrice,
           UnitPriceDiscount,
           LineTotal,
           ModifiedDate
          FROM Sales.SalesOrderDetail
    GO
    --Create an index on the view
    CREATE UNIQUE CLUSTERED INDEX IDX_V1
       ON Sales.vOrderDetails1 (SalesOrderID, ProductID);
    --Select from the materialized view
    SELECT * FROM LS1.adventureworks2019.Sales.vOrderDetails1;
    

    Пример см. в следующей оценке кратности запроса.

    Снимок экрана: запрос индексированного представления на связанном сервере.

  • При выполнении запроса с WHERE предложением можно увеличить оценку кратности с помощью Query Hint OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION')). Этот подход может помочь в некоторых случаях, особенно при присоединении к большим таблицам.

    Примечание.

    Этот метод подходит для случаев, когда представление предоставляет множество строк.

  • При необходимости выполните запрос непосредственно к базовым таблицам вместо представлений на связанном сервере.

См. также