Delen via


Aanname van join-insluiting in de nieuwe kardinaliteitsschatter verslechtert de queryprestaties

Dit artikel helpt u bij het oplossen van prestatieproblemen die kunnen optreden in SQL Server 2014 en latere versies wanneer u uw query's compileert met behulp van de nieuwe kardinaliteitsschatter.

Oorspronkelijke productversie: SQL Server
Oorspronkelijk KB-nummer: 3189675

Symptomen

Bekijk het volgende scenario:

  • U gebruikt SQL Server 2014 of een nieuwere versie.
  • U voert een query uit die joins en niet-joinfilterpredicaten bevat.
  • U compileert de query met behulp van de nieuwe kardinaliteitsraming (SQL Server) (nieuwe CE).

In dit scenario ondervindt u een verslechtering van de queryprestaties.

Dit probleem treedt niet op als u de query compileert met behulp van de verouderde CE.

Oorzaak

Vanaf SQL Server 2014 is de nieuwe kardinaliteitsschatter (nieuwe CE) geïntroduceerd voor databasecompatibiliteitsniveau 120 en hoger. De nieuwe CE wijzigt verschillende veronderstellingen van de verouderde CE in het model dat wordt gebruikt door de Query Optimizer wanneer de kardinaliteit voor verschillende operators en predicaten wordt geschat.

Een van deze wijzigingen is gerelateerd aan de aanname van join-insluiting.

Bij het verouderde CE-model wordt ervan uitgegaan dat gebruikers altijd query's uitvoeren op gegevens die bestaan. Dit betekent dat voor een joinpredicaat dat een equijoin-bewerking voor twee tabellen omvat, de gekoppelde kolommen aan beide zijden van de join bestaan. In aanwezigheid van extra niet-joinfilterpredicaten voor de jointabel, gaat de verouderde CE uit van een bepaald correlatieniveau voor de joinpredicaten en niet-joinfilterpredicaten. Deze impliciete correlatie wordt Simple Containment genoemd.

De nieuwe CE maakt ook gebruik van Base Containment als correlatie. Bij het nieuwe CE-model wordt ervan uitgegaan dat gebruikers mogelijk query's uitvoeren op gegevens die niet bestaan. Dit betekent dat het filterpredicaat voor afzonderlijke tabellen mogelijk niet met elkaar is gecorreleerd. Daarom gebruiken we een probabilistische benadering.

Voor veel praktische scenario's maakt het gebruik van de basisbevattende aanname betere schattingen. Dit zorgt op zijn beurt voor efficiëntere keuzes voor queryplannen. In sommige situaties kan het gebruik van de veronderstelling simple containment echter betere resultaten opleveren. Als dit gebeurt, ondervindt u mogelijk minder efficiënte keuze voor het queryplan wanneer u de nieuwe ce gebruikt in plaats van de verouderde CE.

Zie Verminderde queryprestaties na de upgrade van SQL Server 2012 of eerder naar 2014 of hoger voor meer informatie over het oplossen van problemen met betrekking tot nieuwe CE.

Oplossing

In SQL Server 2014 en latere versies kunt u traceringsvlag 9476 gebruiken om SQL Server af te dwingen de aanname simple containment te gebruiken in plaats van de standaardveronderstelling voor basisbesluiting. Als u de toepassingsquery kunt wijzigen, kunt u beter de queryhint ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS gebruiken na SQL Server 2016 (13.x) SP1. Zie USE HINT voor meer informatie. Bijvoorbeeld:

SELECT * FROM Table1 t1
JOIN Table2 t2
ON t1.Col1 = t2.Col1
WHERE Col1 = 10
OPTION (USE HINT ('ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS'));

Het inschakelen van deze traceringsvlag of het gebruik van de queryhint kan de keuze van het queryplan verbeteren zonder volledig terug te keren naar het verouderde CE-model als aan de volgende voorwaarden wordt voldaan:

  • U ondervindt een suboptimale queryplankeuze die een algehele verminderde prestaties veroorzaakt voor query's die joins en niet-joinfilterpredicaten bevatten.
  • U kunt een aanzienlijke onnauwkeurigheid in een schatting van de joinkardinaliteit controleren (dat wil gezegd het werkelijke versus geschatte aantal rijen dat aanzienlijk verschilt).
  • Deze onnauwkeurigheid bestaat niet wanneer u query's compileert met behulp van de verouderde CE.

U kunt deze traceringsvlag globaal, op sessieniveau of op queryniveau inschakelen.

Notitie

Het onjuist gebruiken van traceringsvlagmen kan de prestaties van uw workload verminderen. Zie Hints (Transact-SQL) - Query voor meer informatie.