Aracılığıyla paylaş


T-SQL performans sorunları

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen ÖrneğiMicrosoft Fabric'te SQL veritabanı

Veritabanı projenizdeki T-SQL kodunu analiz ettiğinizde, bir veya daha fazla uyarı performans sorunları olarak kategorilere ayrılmış olabilir. Aşağıdaki durumlardan kaçınmak için bir performans sorununu gidermeniz gerekir:

  • Kod yürütülürken bir tablo taraması gerçekleşir.

Genel olarak, tabloda çok az veri varsa bir performans sorununu gizleyebilirsiniz ve tarama performansın önemli ölçüde düşmesine neden olmaz.

Sağlanan kurallar aşağıdaki performans sorunlarını tanımlar:

SR0004: IN koşullarında test ifadeleri olarak dizinleri olmayan sütunları kullanmaktan kaçının

Bir IN koşulunun parçası olarak dizine alınmamış bir veya daha fazla sütunu referans alan bir WHERE yan tümcesi kullanırsanız, tablo taramasına neden olursunuz. Tablo taraması performansı azaltır.

İhlalleri düzeltme

Bu sorunu çözmek için aşağıdaki değişikliklerden birini yapmanız gerekir:

  • IN koşulunu yalnızca dizini olan sütunlara başvuracak şekilde değiştirin.
  • IN koşulunun başvurduğu ve henüz dizinlenmemiş olan herhangi bir sütun için bir dizin ekleyin.

Example

Bu örnekte, basit bir SELECT deyimi dizine sahip olmayan [c1] sütununa başvurur. İkinci deyim, bu uyarıyı çözmek için ekleyebileceğiniz bir dizin tanımlar.

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: LIKE koşullarında "%" ile başlayan desenleri kullanmaktan kaçının

Sütun içinde herhangi bir yerde bulunabilecek metinleri aramak için WHERE yan tümcesinde '%pattern metin' gibi bir LIKE ifadesi kullanırsanız tablo taramasına neden olabilirsiniz.

İhlalleri düzeltme

Bu sorunu çözmek için, arama dizesini joker karakter (%) olmayan bir karakterle başlayacak şekilde değiştirmeniz veya tam metin dizini oluşturmanız gerekir.

Example

İlk örnekte, arama dizesi joker karakterle başladığından SELECT deyimi tablo taramasına neden olur. İkinci örnekte, arama dizesi joker karakterle başlamadığından, ifade dizin araması gerçekleştirir. Dizin araması yalnızca WHERE yan tümcesi ile eşleşen satırları alır.

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: Sütun dizinini kullanmak için sütun başvurularını karşılaştırma işlecinin bir tarafına taşıma

Kodunuz, sütun başvurusu içeren bir ifadeyi karşılaştırırsa tablo taramasına neden olabilir.

İhlalleri düzeltme

Bu sorunu çözmek için, sütun başvurusunun bir ifadenin içinde değil, karşılaştırma işlecinin bir tarafında tek başına görünmesi için karşılaştırmayı yeniden işlemeniz gerekir. Karşılaştırma işlecinin bir tarafında tek başına sütun başvurusu olan kodu çalıştırdığınızda, SQL Server sütun dizinini kullanabilir ve tablo taraması yapılmaz.

Example

İlk yordamda WHERE yan tümcesi, karşılaştırmanın bir parçası olarak ifadede [c1] sütununu içerir. İkinci yordamda karşılaştırma sonuçları aynıdır ancak hiçbir zaman tablo taraması gerektirmez.

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: İfadelerde null atanabilir sütunlarda ISNULL(sütun, varsayılan_değer) kullanın

Kodunuz iki NULL değeri veya değeri başka bir NULL değerle karşılaştırıyorsa, kodunuz bilinmeyen bir sonuç döndürür.

İhlalleri düzeltme

Bir işlevde değer içerebilen NULL her sütunu kaydırarak karşılaştırma ifadelerindeki NULL değerlerin nasıl işleneceğini ISNULL açıkça belirtmelisiniz.

Example

Bu örnekte basit bir tablo tanımı ve iki saklı yordam gösterilmektedir. Tablo, c2bir değer içerebilen bir NULL sütun içerir. İlk yordam olan ProcedureWithWarning, sabit bir değerle karşılaştırır c2 . İkinci yordam, işlevine bir çağrı ile sarmalayarak c2 sorunu düzeltir ISNULL .

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: WHERE koşullarından deterministik işlev çağrılarını ayıklama

WHERE koşulunda, değeri seçilen verilere bağlı değilse işlev çağrısı belirleyicidir. Bu tür çağrılar, veritabanı performansını düşüren gereksiz tablo taramalarına neden olabilir.

İhlalleri düzeltme

Bu sorunu çözmek için çağrının sonucunu WHERE koşulunda kullandığınız bir değişkene atayabilirsiniz.

Example

İlk örnekte saklı yordam WHERE koşulunda deterministik işlev çağrısı ABS(@param1)içerir. İkinci örnekte, geçici bir değişken çağrının sonucunu tutar.

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