Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
SQL-databas i Microsoft Fabric
När du analyserar T-SQL-koden i databasprojektet kan en eller flera varningar kategoriseras som prestandaproblem. Du bör åtgärda ett prestandaproblem för att undvika följande situation:
- En tabellgenomsökning sker när koden körs.
I allmänhet kan du förhindra prestandaproblem om tabellen innehåller så lite data att en genomsökning inte leder till att prestandan minskar avsevärt.
De angivna reglerna identifierar följande prestandaproblem:
- SR0004: Undvik att använda kolumner som inte har index som testuttryck i IN-predikater
- SR0005: Undvik att använda mönster som börjar med "%" i LIKE-predikat
- SR0006: Flytta en kolumnreferens till ena sidan av en jämförelseoperator för att använda ett kolumnindex
- SR0007: Använd ISNULL(column, default_value) på nullbara kolumner i uttryck
- SR0015: Extrahera deterministiska funktionsanrop från WHERE-predikat
SR0004: Undvik att använda kolumner som inte har index som testuttryck i IN-predikater
Du orsakar en tabellgenomsökning om du använder en WHERE-sats som refererar till en eller flera kolumner som inte indexeras som en del av en IN-predikat. Tabellgenomsökningen minskar prestandan.
Så här åtgärdar du överträdelser
För att lösa det här problemet måste du göra någon av följande ändringar:
- Ändra IN-predikatet till att endast referera till de kolumner som har ett index.
- Lägg till ett index i en kolumn som IN predikat refererar till och som inte redan har ett index.
Example
I det här exemplet refererar en enkel SELECT-instruktion till en kolumn, [c1], som inte hade något index. Den andra instruktionen definierar ett index som du kan lägga till för att lösa den här varningen.
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: Undvik att använda mönster som börjar med "%" i LIKE-predikat
Du kan orsaka en tabellgenomsökning om du använder en WHERE-sats som innehåller ett LIKE-predikat som "%pattern sträng" för att söka efter text som kan förekomma var som helst i en kolumn.
Så här åtgärdar du överträdelser
För att lösa det här problemet bör du ändra söksträngen så att den börjar med ett tecken som inte är ett jokertecken (%), eller så bör du skapa ett fulltextindex.
Example
I det första exemplet orsakar SELECT-instruktionen en tabellgenomsökning eftersom söksträngen börjar med ett jokertecken. I det andra exemplet föranleder instruktionen en indexsökning eftersom söksträngen inte börjar med ett jokertecken. En indexsökning hämtar endast de rader som matchar WHERE-satsen.
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: Flytta en kolumnreferens till ena sidan av en jämförelseoperator för att använda ett kolumnindex
Koden kan orsaka en tabellgenomsökning om den jämför ett uttryck som innehåller en kolumnreferens.
Så här åtgärdar du överträdelser
För att lösa det här problemet måste du omarbeta jämförelsen så att kolumnreferensen visas ensam på ena sidan av jämförelseoperatorn i stället för inuti ett uttryck. När du kör koden som har kolumnreferensen ensam på ena sidan av jämförelseoperatorn kan SQL Server använda kolumnindexet och ingen tabellgenomsökning utförs.
Example
I den första proceduren innehåller en WHERE-sats kolumnen [c1] i ett uttryck som en del av en jämförelse. I den andra proceduren är jämförelseresultaten identiska men kräver aldrig en tabellgenomsökning.
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: Använd ISNULL(column, default_value) på nullbara kolumner i uttryck
Om koden jämför två NULL värden eller ett NULL värde med något annat värde returnerar koden ett okänt resultat.
Så här åtgärdar du överträdelser
Du bör uttryckligen ange hur du hanterar NULL värden i jämförelseuttryck genom att omsluta varje kolumn som kan innehålla ett NULL värde i en ISNULL funktion.
Example
Det här exemplet visar en enkel tabelldefinition och två lagrade procedurer. Tabellen innehåller en kolumn, c2, som kan innehålla ett NULL värde. Den första proceduren, ProcedureWithWarning, jämförs c2 med ett konstant värde. Den andra proceduren åtgärdar problemet genom att omsluta c2 med ett anrop till ISNULL funktionen.
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: Extrahera deterministiska funktionsanrop från WHERE-predikat
I ett WHERE-predikat är ett funktionsanrop deterministiskt om dess värde inte är beroende av valda data. Sådana anrop kan orsaka onödiga tabellgenomsökningar, vilket minskar databasens prestanda.
Så här åtgärdar du överträdelser
För att lösa det här problemet kan du tilldela resultatet av anropet till en variabel som du använder i WHERE-predikatet.
Example
I det första exemplet innehåller den lagrade proceduren ett deterministiskt funktionsanrop, ABS(@param1), i WHERE-predikatet. I det andra exemplet innehåller en tillfällig variabel resultatet av anropet.
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