Megosztás a következőn keresztül:


T-SQL-teljesítményproblémák

A következőkre vonatkozik:SQL ServerAzure SQL DatabaseFelügyelt Azure SQL-példánySQL-adatbázis a Microsoft Fabricben

Ha az adatbázisprojektben elemzi a T-SQL-kódot, egy vagy több figyelmeztetés teljesítményproblémákként kategorizálható. A következő helyzet elkerülése érdekében a teljesítményproblémával kell foglalkoznia:

  • A kód végrehajtásakor táblavizsgálat történik.

Általánosságban elmondható, hogy ha a tábla olyan kevés adatot tartalmaz, hogy a vizsgálat nem eredményezi a teljesítmény jelentős csökkenését, előfordulhat, hogy elnyom egy teljesítményproblémát.

A megadott szabályok a következő teljesítményproblémákat azonosítják:

SR0004: Ne használjon olyan oszlopokat, amelyek nem rendelkeznek indexekkel tesztkifejezésként az IN predikátumokban

Táblavizsgálatot akkor okoz, ha olyan WHERE záradékot használ, amely egy vagy több olyan oszlopra hivatkozik, amely nem indexelt egy IN-predikátum részeként. A táblavizsgálat csökkenti a teljesítményt.

Szabálysértések kijavítása

A probléma megoldásához hajtsa végre az alábbi módosítások egyikét:

  • Módosítsa az IN predikátumot úgy, hogy csak az indexet tartalmazó oszlopokra hivatkozzon.
  • Adjon hozzá indexet bármely olyan oszlophoz, amelyre az IN predikátum hivatkozik, és amely még nem rendelkezik indexel.

Example

Ebben a példában egy egyszerű SELECT utasítás egy [c1] oszlopra hivatkozik, amely nem tartalmaz indexet. A második utasítás egy indexet határoz meg, amelyet hozzáadhat a figyelmeztetés feloldásához.

CREATE PROCEDURE [dbo].[Procedure3WithWarnings]
AS
SELECT [Comment]
FROM [dbo].[Table2]
WHERE [c1] IN (1, 2, 3)

CREATE INDEX [IX_Table2_C1]
ON [dbo].[Table2] (c1);

SR0005: Kerülje a "%" kezdetű mintákat a LIKE-predikátumokban

Táblavizsgálatot okozhat, ha egy LIKE-predikátumot tartalmazó WHERE záradékot használ, például "%pattern sztringet" az oszlop bármely pontján előforduló szöveg kereséséhez.

Szabálysértések kijavítása

A probléma megoldásához módosítsa a keresési sztringet úgy, hogy az ne helyettesítő karakterrel (%) kezdődjön, vagy hozzon létre egy teljes szöveges indexet.

Example

Az első példában a SELECT utasítás táblavizsgálatot okoz, mert a keresési sztring helyettesítő karakterrel kezdődik. A második példában az utasítás indexkeresést okoz, mert a keresési sztring nem helyettesítő karakterrel kezdődik. Az indexkeresések csak a WHERE záradéknak megfelelő sorokat kérik le.

SELECT [dbo].[Table2].[ID], [dbo].[Table2].[c1], [dbo].[Table2].[c2], [dbo].[Table2].[c3], [dbo].[Table2].[Comment]
FROM dbo.[Table2]
WHERE Comment LIKE '%pples'

SELECT [dbo].[Table2].[ID], [dbo].[Table2].[c1], [dbo].[Table2].[c2], [dbo].[Table2].[c3], [dbo].[Table2].[Comment]
FROM dbo.[Table2]
WHERE Comment LIKE 'A%'

SR0006: Oszlophivatkozás áthelyezése az összehasonlító operátor egyik oldalára oszlopindex használatához

A kód táblavizsgálatot okozhat, ha egy oszlophivatkozást tartalmazó kifejezést hasonlít össze.

Szabálysértések kijavítása

A probléma megoldásához át kell dolgoznia az összehasonlítást, hogy az oszlophivatkozás az összehasonlító operátor egyik oldalán jelenjen meg, és ne egy kifejezésen belül. Amikor az összehasonlító operátor egyik oldalán futtatja az oszlophivatkozást tartalmazó kódot, az SQL Server használhatja az oszlopindexet, és nem végez táblavizsgálatot.

Example

Az első eljárásban a WHERE záradék egy összehasonlítás részeként egy kifejezés [c1] oszlopát tartalmazza. A második eljárásban az összehasonlítási eredmények azonosak, de nem igényelnek táblavizsgálatot.

CREATE PROCEDURE [dbo].[Procedure3WithWarnings]
@param1 int
AS
SELECT [c1], [c2], [c3], [Comment]
FROM [dbo].[Table2]
WHERE ([c1] + 5 > @param1)

CREATE PROCEDURE [dbo].[Procedure3Fixed]
@param1 int
AS
SELECT [c1], [c2], [c3], [Comment]
FROM [dbo].[Table2]
WHERE ([c1] > (@param1 - 5))

SR0007: Az ISNULL(oszlop, default_value) használata a kifejezések null értékű oszlopainál

Ha a kód két NULL értéket vagy egy NULL értéket hasonlít össze bármely más értékkel, a kód ismeretlen eredményt ad vissza.

Szabálysértések kijavítása

Világosan meg kell adnia, hogyan kezelje a NULL értékeket az összehasonlító kifejezésekben, azokat az egyes oszlopokat egy NULL függvénybe foglalva, amelyek tartalmazhatnak ISNULL értéket.

Example

Ez a példa egy egyszerű tábladefiníciót és két tárolt eljárást mutat be. A tábla tartalmaz egy oszlopot, c2amely tartalmazhat egy NULL értéket. Az első eljárás ProcedureWithWarningegy állandó értékkel hasonlít össze c2 . A második eljárás megoldja a problémát azzal, hogy a c2-t a ISNULL függvény hívásával zárja be.

CREATE TABLE [dbo].[Table1]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL PRIMARY KEY,
[c2] INT
)
ON [PRIMARY]

CREATE PROCEDURE [dbo].[ProcedureWithWarning]
AS
BEGIN
SELECT COUNT(*) FROM [dbo].[Table1]
 WHERE [c2] > 2;
END

CREATE PROCEDURE [dbo].[ProcedureFixed]
AS
BEGIN
SELECT COUNT(*) FROM [dbo].[Table1]
WHERE ISNULL([c2],0) > 2;
END

SR0015: Determinisztikus függvényhívások kinyerése WHERE predikátumokból

A WHERE predikátumban a függvényhívás determinisztikus, ha az értéke nem függ a kiválasztott adatoktól. Az ilyen hívások szükségtelen táblavizsgálatokat okozhatnak, ami csökkenti az adatbázis teljesítményét.

Szabálysértések kijavítása

A probléma megoldásához hozzárendelheti a hívás eredményét a WHERE predikátumban használt változóhoz.

Example

Az első példában a tárolt eljárás tartalmaz egy determinisztikus függvényhívást a ABS(@param1)WHERE predikátumban. A második példában egy ideiglenes változó tárolja a hívás eredményét.

CREATE PROCEDURE [dbo].[Procedure2WithWarning]
@param1 INT = 0,
AS
BEGIN
SELECT [c1], [c2], [c3], [SmallString]
FROM [dbo].[Table1]
WHERE [c2] > ABS(@param1)
END

CREATE PROCEDURE [dbo].[Procedure2Fixed]
@param1 INT = 0,
AS
BEGIN
DECLARE @AbsOfParam1 INT
SET @AbsOfParam1 = ABS(@param1)

SELECT [c1], [c2], [c3], [SmallString]
FROM [dbo].[Table1]
WHERE [c2] > @AbsOfParam1
END