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
Azure SQL Database
Azure SQL Managed Instance
SQL-database in Microsoft Fabric
Wanneer u de T-SQL-code in uw databaseproject analyseert, kunnen een of meer waarschuwingen worden gecategoriseerd als prestatieproblemen. U moet een prestatieprobleem oplossen om de volgende situatie te voorkomen:
- Er wordt een tabelscan uitgevoerd wanneer de code wordt uitgevoerd.
Over het algemeen kunt u een prestatieprobleem onderdrukken als de tabel zo weinig gegevens bevat dat een scan de prestaties niet aanzienlijk zal laten dalen.
De opgegeven regels identificeren de volgende prestatieproblemen:
- SR0004: Vermijd het gebruik van kolommen die geen indexen hebben als testexpressies in IN-predicaten
- SR0005: Vermijd het gebruik van patronen die beginnen met "%" in LIKE predicaten
- SR0006: Een kolomverwijzing naar één kant van een vergelijkingsoperator verplaatsen om een kolomindex te gebruiken
- SR0007: Gebruik ISNULL(column, default_value) voor nullable kolommen in expressies
- SR0015: Deterministische functieaanroepen extraheren uit WHERE predicaten
SR0004: Vermijd het gebruik van kolommen die geen indexen hebben als testexpressies in IN-predicaten
U veroorzaakt een tabelscan als u een WHERE-component gebruikt die verwijst naar een of meer kolommen die niet zijn geïndexeerd als onderdeel van een IN-predicaat. De tabelscan vermindert de prestaties.
Hoe schendingen op te lossen
U kunt dit probleem oplossen door een van de volgende wijzigingen aan te brengen:
- Wijzig het PREdicaat IN om alleen te verwijzen naar de kolommen met een index.
- Voeg een index toe aan een kolom die door het PREdicaat IN wordt verwezen en die nog geen index heeft.
Example
In dit voorbeeld verwijst een eenvoudige SELECT-instructie naar een kolom ,[c1], die geen index had. De tweede instructie definieert een index die u kunt toevoegen om deze waarschuwing op te lossen.
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: Vermijd het gebruik van patronen die beginnen met "%" in LIKE predicaten
U kunt een tabelscan veroorzaken als u een WHERE-component gebruikt die een LIKE-predicaat bevat, zoals '%pattern tekenreeks' om te zoeken naar tekst die overal in een kolom kan voorkomen.
Hoe schendingen op te lossen
Als u dit probleem wilt oplossen, moet u de zoektekenreeks wijzigen zodat deze begint met een teken dat geen jokerteken (%) is of u moet een volledige-tekstindex maken.
Example
In het eerste voorbeeld veroorzaakt de SELECT-instructie een tabelscan omdat de zoektekenreeks begint met een jokerteken. In het tweede voorbeeld veroorzaakt de instructie een indexzoekopdracht omdat de zoekreeks niet begint met een jokerteken. Een index zoekt alleen de rijen die overeenkomen met de WHERE-component.
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: Een kolomverwijzing naar één zijde van een vergelijkingsoperator verplaatsen om een kolomindex te gebruiken
Uw code kan een tabelscan veroorzaken als er een expressie wordt vergeleken die een kolomreferentie bevat.
Hoe schendingen op te lossen
U kunt dit probleem oplossen door de vergelijking zo te bewerken dat de kolomverwijzing alleen aan één kant van de vergelijkingsoperator wordt weergegeven in plaats van binnen een expressie. Wanneer u de code uitvoert die alleen de kolomverwijzing aan één kant van de vergelijkingsoperator bevat, kan SQL Server de kolomindex gebruiken en wordt er geen tabelscan uitgevoerd.
Example
In de eerste procedure bevat een WHERE-component kolom [c1] in een expressie als onderdeel van een vergelijking. In de tweede procedure zijn de vergelijkingsresultaten identiek, maar vereisen ze nooit een tabelscan.
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: ISNULL(column, default_value) gebruiken voor null-kolommen in expressies
Als uw code twee NULL waarden of een waarde vergelijkt met een NULL andere waarde, retourneert uw code een onbekend resultaat.
Hoe schendingen op te lossen
U moet expliciet aangeven hoe u waarden in vergelijkingsexpressies kunt verwerken NULL door elke kolom te verpakken die een NULL waarde in een ISNULL functie kan bevatten.
Example
In dit voorbeeld ziet u een eenvoudige tabeldefinitie en twee opgeslagen procedures. De tabel bevat een kolom, c2die een NULL waarde kan bevatten. De eerste procedure, ProcedureWithWarningvergelijkt c2 met een constante waarde. Bij de tweede procedure wordt het probleem opgelost door c2 te verpakken met een aanroep naar de ISNULL functie.
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: Deterministische functieaanroepen extraheren uit WHERE-predicaten
In een WHERE-predicaat is een functieaanroep deterministisch als de waarde ervan niet afhankelijk is van de geselecteerde gegevens. Dergelijke aanroepen kunnen onnodige tabelscans veroorzaken, waardoor de databaseprestaties afnemen.
Hoe schendingen op te lossen
U kunt dit probleem oplossen door het resultaat van de aanroep toe te wijzen aan een variabele die u in het WHERE-predicaat gebruikt.
Example
In het eerste voorbeeld bevat de opgeslagen procedure een deterministische functieaanroep, ABS(@param1)in het predicaat WHERE. In het tweede voorbeeld bevat een tijdelijke variabele het resultaat van de aanroep.
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