Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Van toepassing op: SQL Server
Symptomen
Het uitvoeren van een query op weergaven op een gekoppelde server kost meer tijd dan het rechtstreeks uitvoeren van dezelfde query op een basistabel op de gekoppelde server.
Oorzaak
Het uitvoeren van een query voor een weergave en een basistabel resulteert in een ander gedrag vanwege de schatting van de gegevenskardinaliteit, die wordt gebruikt voor het berekenen van het verwachte aantal geretourneerde rijen. Het getal voor het uitvoeren van queryweergaven wordt ingesteld op een constante waarde van 10.000, terwijl het aantal voor het uitvoeren van query's op basistabellen wordt afgeleid van statistische informatie.
Kardinaliteitschatting op een basistabel die wordt opgevraagd door gekoppelde servers
De Microsoft OLE DB-provider (SQLOLEDB) (niet meer onderhouden) of Microsoft® OLE DB-stuurprogramma 18 voor SQL Server® (MSOLEDBSQL) ondersteunen beide distributiestatistieken op basistabellen. SQL Server kan de statistieken en het histogram op gekoppelde servers op dezelfde manier gebruiken als bij elke reguliere query. Als u bijvoorbeeld een gekoppelde server met de naam LS1 maakt die de AdventureWorks2019 database met de Sales.SalesOrderDetail tabel bevat, kunnen de volgende query's gebruikmaken van het statistische histogram:
SELECT * FROM LS1.AdventureWorks2019.Sales.SalesOrderDetail;
SELECT * FROM LS1.AdventureWorks2019.Sales.SalesOrderDetail WHERE SalesOrderID=43659;
In de volgende grafische queryplannen ziet u het geschatte aantal rijen dat wordt geretourneerd voor elke externe query.
Kardinaliteitschatting voor weergaven die worden opgevraagd door gekoppelde servers
Gekoppelde serverquery's voor weergaven maken geen gebruik van schatting van kardinaliteit op basis van statistieken. De kardinaliteitschatting voor een weergave is een constante waarde van 10.000. De volgende test illustreert dit:
Maak een weergave met de naam
dbo.View1die verwijst naar deSales.SalesOrderDetailtabel uit deAdventureWorks2019database van de gekoppelde server LS1.USE AdventureWorks2019; GO CREATE VIEW [dbo].[view1] AS SELECT * FROM Sales.SalesOrderDetail;Query's uitvoeren op de weergave op afstand.
SELECT * FROM LS1.AdventureWorks2019.dbo.view1;De kardinaliteitschatting van de query toont precies 10.000 rijen.
Kardinaliteitschatting voor een weergave die wordt opgevraagd door gekoppelde servers met WHERE-component
Als u een query uitvoert met de WHERE component voor weergaven op een gekoppelde server, is de kardinaliteitschatting voor weergaven ook een constante waarde. De waarde is echter afhankelijk van het compatibiliteitsniveau van de database.
Notitie
De schattingswaarde voor kardinaliteit wordt niet beïnvloed door het compatibiliteitsniveau van de database waarin de weergave is gedefinieerd.
- Voor een databasecompatibiliteitsniveau van 120 of hoger (nieuwe versie van kardinaliteitsschatter) is de kardinaliteitsraming 100.
- Voor een databasecompatibiliteitsniveau van 110 of lager (verouderde kardinaliteitsschatter) is de kardinaliteitschatting 1000.
Zie de volgende query's voor een voorbeeld:
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'));
Zie de volgende kardinaliteitschatting van de query's voor een voorbeeld.
Oplossing
In de meeste gevallen is er geen actie nodig omdat de meeste toepassingsworkloads niet worden beïnvloed door de kardinaliteitschatting van weergaven wanneer er query's worden uitgevoerd vanaf gekoppelde servers. Als de werkbelasting wordt beïnvloed, gebruikt u een van de volgende methoden:
Werk de weergave bij en wijzig deze als een geïndexeerde weergave. De geïndexeerde weergave heeft ten minste één index met bijbehorende statistieken. Zie de volgende query's om een geïndexeerde weergave te maken en er query's op uit te voeren.
Notitie
Met deze methode worden werkelijke statistieken weergegeven die de onderliggende gegevens vertegenwoordigen.
--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;Zie de volgende kardinaliteitschatting van de query voor een voorbeeld.
Als u een query uitvoert met de
WHEREcomponent, kunt u de kardinaliteitschatting verhogen met behulp van deQuery Hint OPTION(USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION')). Deze aanpak kan in sommige gevallen helpen, met name bij het samenvoegen met grote tabellen.Notitie
Deze methode is geschikt voor gevallen waarin in de weergave veel rijen worden weergegeven.
Voer de query rechtstreeks uit op de basistabellen in plaats van weergaven op de gekoppelde server, indien van toepassing.