Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Berlaku untuk:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Database SQL di Microsoft Fabric
Saat Anda menganalisis kode T-SQL dalam proyek database Anda, satu atau beberapa peringatan mungkin dikategorikan sebagai masalah performa. Anda harus mengatasi masalah performa untuk menghindari situasi berikut:
- Pemindaian tabel terjadi saat kode dijalankan.
Secara umum, Anda mungkin menekan masalah performa jika tabel berisi begitu sedikit data sehingga pemindaian tidak akan menyebabkan performa turun secara signifikan.
Aturan yang disediakan mengidentifikasi masalah performa berikut:
- SR0004: Hindari menggunakan kolom yang tidak memiliki indeks sebagai ekspresi pengujian dalam predikat IN
- SR0005: Hindari menggunakan pola yang dimulai dengan "%" dalam predikat LIKE
- SR0006: Memindahkan referensi kolom ke satu sisi operator perbandingan untuk menggunakan indeks kolom
- SR0007: Gunakan ISNULL(column, default_value) pada kolom nullable dalam ekspresi
- SR0015: Mengekstrak panggilan fungsi deterministik dari predikat WHERE
SR0004: Hindari menggunakan kolom yang tidak memiliki indeks sebagai ekspresi pengujian dalam predikat IN
Anda akan memicu pemindaian tabel jika Anda menggunakan klausa WHERE yang mengacu pada satu atau beberapa kolom yang tidak diindeks dalam predikat IN. Pemindaian tabel mengurangi performa.
Cara memperbaiki pelanggaran
Untuk mengatasi masalah ini, Anda harus membuat salah satu perubahan berikut:
- Ubah predikat IN untuk mereferensikan hanya kolom yang memiliki indeks.
- Tambahkan indeks ke kolom apa pun yang dirujuk predikat IN dan yang belum memiliki indeks.
Example
Dalam contoh ini, pernyataan SELECT sederhana mereferensikan kolom, [c1], yang tidak memiliki indeks. Pernyataan kedua menentukan indeks yang dapat Anda tambahkan untuk mengatasi peringatan ini.
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: Hindari menggunakan pola yang dimulai dengan "%" dalam predikat LIKE
Anda dapat menyebabkan pemindaian tabel jika Anda menggunakan klausa WHERE yang berisi predikat LIKE seperti '%pattern string' untuk mencari teks yang dapat terjadi di mana saja dalam kolom.
Cara memperbaiki pelanggaran
Untuk mengatasi masalah ini, Anda harus mengubah string pencarian sehingga dimulai dengan karakter yang bukan wildcard (%), atau Anda harus membuat indeks teks penuh.
Example
Dalam contoh pertama, pernyataan SELECT menyebabkan pemindaian seluruh tabel karena string pencarian dimulai dengan karakter wildcard. Dalam contoh kedua, pernyataan tersebut menyebabkan pencarian indeks karena string pencarian tidak dimulai dengan karakter wildcard. Pencarian indeks hanya mengambil baris yang cocok dengan klausa WHERE.
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: Memindahkan referensi kolom ke satu sisi operator perbandingan untuk menggunakan indeks kolom
Kode Anda dapat menyebabkan pemindaian tabel jika membandingkan ekspresi yang berisi referensi kolom.
Cara memperbaiki pelanggaran
Untuk mengatasi masalah ini, Anda harus mengerjakan ulang perbandingan sehingga referensi kolom muncul sendiri di satu sisi operator perbandingan, bukan di dalam ekspresi. Saat Anda menjalankan kode yang memiliki referensi kolom saja di satu sisi operator perbandingan, SQL Server dapat menggunakan indeks kolom, dan tidak ada pemindaian tabel yang dilakukan.
Example
Dalam prosedur pertama, klausa WHERE menyertakan kolom [c1] dalam ekspresi sebagai bagian dari perbandingan. Dalam prosedur kedua, hasil perbandingan identik tetapi tidak pernah memerlukan pemindaian tabel.
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: Gunakan ISNULL(column, default_value) pada kolom nullable dalam ekspresi
Jika kode Anda membandingkan dua NULL nilai atau NULL nilai dengan nilai lain, kode Anda mengembalikan hasil yang tidak diketahui.
Cara memperbaiki pelanggaran
Anda harus secara eksplisit menunjukkan cara menangani NULL nilai dalam ekspresi perbandingan dengan membungkus setiap kolom yang dapat berisi NULL nilai dalam ISNULL fungsi.
Example
Contoh ini menunjukkan definisi tabel sederhana dan dua prosedur tersimpan. Tabel berisi kolom, c2, yang dapat berisi NULL nilai. Prosedur pertama, ProcedureWithWarning, dibandingkan dengan nilai konstanta c2 . Prosedur kedua memperbaiki masalah dengan membungkus c2 dengan panggilan fungsi 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: Mengekstrak panggilan fungsi deterministik dari predikat WHERE
Dalam predikat WHERE, panggilan fungsi bersifat deterministik jika nilainya tidak bergantung pada data yang dipilih. Panggilan tersebut dapat menyebabkan pemindaian tabel yang tidak perlu, yang mengurangi performa database.
Cara memperbaiki pelanggaran
Untuk mengatasi masalah ini, Anda dapat menetapkan hasil panggilan ke variabel yang Anda gunakan dalam predikat WHERE.
Example
Dalam contoh pertama, prosedur tersimpan mencakup panggilan fungsi deterministik, ABS(@param1), dalam predikat WHERE. Dalam contoh kedua, variabel sementara menyimpan hasil panggilan.
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