DECLARE @p0 FLOAT = 1.2840000000000000e+001,
@p1 FLOAT = 5.6609859999999998e+001,
@p2 VARCHAR(2) = 'da'
SELECT top 200
latitude,
longitute,
language_desc
FROM dbo.Geo
WHERE (latitude = @p0) AND (longitute = @p1) AND (language_desc = @p2)
Og her ses det hvorfor vi har en constant scan, det er pga. implicit conversions i vores where clause.
Da databaserne og SQL forespørgslen er 100% ens i begge versioner, betyder det også at der er implicit_conversion i den gamle 2008 version.. men hvorfor performer det bedre?
Min mistanke gik på om den interne funktion <Intrinsic FunctionName=”GetRangeThroughConvert”> var ændret imellem de 2 versioner og derved performer lidt langsommere i lige netop dette eksempel.
Så for at finde ud af det, laver jeg en lille test.
Jeg opretter 2 databaser:
implicit:_conversion
Inden jeg helt kaster mig ud i testen, så er det ret let at fikse den implicit:_conversion da datatyperne i tabellen er af typen decimal, så skal variablen selvfølgelig også være samme datatype. Da det kaldende program var egenudviklet hos kunden var det let for dem at rette datatypen til. Dette betød at performance gik fra 6-8000 requests i timen til 130000 requests i timen. Jeg siger det ofte når jeg underviser: husk nu at have styr på datatyperne, det betyder faktisk en del i performance.
Anyways tilbage til testen. Herunder kommer resultatet af testen.Til min overraskelse så ligger forskellen i performance i den tid SQL 2017 bruger på at compile Query, det performer langsommere end på 2008. Det ser ud til at det skifter mellem version 2012 og 2014.
Jeg benytter mig af nogle traceflags for at se det plantree SQL Serverens optimizer laver til Query.
QUERY:
SET STATISTICS IO, TIME ON;
GO
DBCC TRACEON(3604)
DECLARE @p0 FLOAT = 1.2840000000000000e+001,
@p1 FLOAT = 5.6609859999999998e+001,
@p2 VARCHAR(2) = 'da'
SELECT top 200
latitude,
longitute,
language_desc
FROM dbo.Geo
WHERE (latitude = @p0) AND (longitute = @p1) AND (language_desc = @p2)
OPTION(RECOMPILE,QUERYTRACEON 8605, QUERYTRACEON 8675)
<ScalarOperator ScalarString="GetRangeThroughConvert([@p0],[@p0],(62))">
<Intrinsic FunctionName="GetRangeThroughConvert">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@p0" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Column="@p0" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Const ConstValue="(62)" />
</ScalarOperator>
</Intrinsic>
</ScalarOperator>
SQL2017:
SQL2008:
Spørgsmålet, som jeg endnu ikke har testet af, er hvis planen er cahed og bliver genbrugt, er der så forskel i performance?
Har du SQL Query, der performer knapt så optimalt, som du godt kunne ønske dig, eller vil du bare gerne have kigget din SQL Server igennem med henblik på performance optimering, så tage endelig fat i mig eller en af mine dygtige kollegaer i Unit IT; ring gerne på tlf.: 88 33 33 33