Saran untuk mendiagnosis permintaan lambat "terkadang"

20

Saya memiliki prosedur tersimpan yang mengembalikan hasil dari tampilan yang diindeks melalui indeks penutup. Biasanya, ini berjalan cepat (~ 10 ms), kadang-kadang bisa berjalan hingga 8 detik.

Berikut ini contoh eksekusi acak (catatan: ini bukan yang lambat, tetapi teks kueri sama kecuali nilai yang diteruskan):

declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)

exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2

Inilah SPROC:

ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
    @LocationIds IdentityType READONLY,
    @StatusType TINYINT
AS
BEGIN
    SET NOCOUNT ON;

    SELECT      -- lots of fields
    FROM        [dbo].[ListingSearchView][a] WITH (NOEXPAND)
    INNER JOIN  @LocationIds [b] ON [a].[LocationId] = [b].[Id]
    WHERE       [a].[StatusType] = @statusType
    OPTION (RECOMPILE);

(catatan: saya menambahkan OPTION (RECOMPILE)petunjuk baru-baru ini setelah beberapa saran, tetapi tidak membantu.

Inilah indeks penutup (catatan: tampilan juga memiliki indeks berkerumun ListingId, yang unik)

CREATE NONCLUSTERED INDEX [IX_ListingSearchView_ForAPI] ON [dbo].[ListingSearchView]
(
    [LocationId] ASC,
    [StatusType] ASC
)
INCLUDE ( -- all the fields in the query) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

Saya menaruh jejak profiler, dengan statistik XML showplan.

Ini yang lambat (6 detik), dan paket yang relevan: masukkan deskripsi gambar di sini

Tampak persis seperti yang saya harapkan, dan merupakan rencana yang sama ketika kueri cepat.

Berikut adalah memperbesar bagian rencana yang mahal, jika itu membantu: masukkan deskripsi gambar di sini

Berikut adalah skema lengkap dari tabel view / backing, jika itu membantu: https://pastebin.com/wh1sRcbQ

Catatan:

  • Indeks telah didefrag, statistik terkini.
  • Awalnya permintaan tidak sejalan dengan tampilan, tetapi saya pindah ke SPROC untuk mencoba dan membantu menstabilkan. Tidak membantu
  • Menambahkan WITH OPTION (RECOMPILE);petunjuk (tidak berfungsi, jadi tidak bisa mengendus parameter?)
  • Pertanyaan lain dalam sistem juga terkadang berjalan lambat, dan mereka juga tidak memiliki masalah yang jelas dalam rencana mereka.
  • Bisa jadi mengunci? Tidak yakin cara mengonfirmasi.

Ada ide tentang apa yang bisa saya coba selanjutnya?

Terima kasih

RPM1984
sumber
1
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan . Semua orang: Silakan gunakan fasilitas itu untuk diskusi lebih lanjut tentang pertanyaan ini.
Paul White mengatakan GoFundMonica
tautan yang diberikan tidak berfungsi. kueri prok langsung, ada perbedaan besar antara jumlah aktual dan taksiran baris yang menjadi perhatian. Saya pikir masalahnya terletak pada tampilan kueri. Saya pikir tidak cukup data. Itu harus dekat
KumarHarsh
Sudahkah Anda mencoba menjalankan WhoIsActive (oleh Adam Machanic) saat kueri berjalan? whoisactive.com Ini termasuk informasi tentang tugas-tugas menunggu, yang seharusnya mengarahkan Anda ke arah yang benar.
MJH
Apakah Anda menghilangkan sesuatu di luar DB yang menyebabkan hal ini. Mungkin beberapa aplikasi lain menyebabkan penyimpanan IO sinkron untuk dibagi dengan DB?
Johan

Jawaban:

2

Saya benar-benar tidak berpikir menggunakan OPTION (RECOMPILE)cara yang efektif untuk menghilangkan kemungkinan mengendus parameter.

Parameter sniffing terjadi ketika SQL bingung tentang permintaan tertentu dan berpikir itu baru karena melihat parameter baru. Ini lambat karena butuh waktu ekstra untuk menghasilkan rencana eksekusi baru.

Semua yang dilakukan opsi adalah memaksa SQL untuk menghasilkan rencana baru setiap kali yang merupakan hal yang hampir sama. Sebagai gantinya, Anda mungkin ingin mempertimbangkan untuk menambahkan parameter default menggunakan petunjuk ini:

OPTION(OPTIMIZE FOR(@LocationIds='xx',@StatusType='xx'))

Saat memilih parameter untuk default, pastikan untuk menggunakan set yang representatif secara statistik.
Itu akan memaksa rencana yang sama untuk digunakan setiap waktu dan menghilangkan kemungkinan mengendus parameter. Setelah Anda melakukannya, dan menentukan itu tidak membantu, maka mungkin aman untuk mengabaikan kemungkinan menghirup parameter.

Penembak McGavin
sumber
1

Mungkin mencoba memaksakan urutan, jadi Anda mungkin selalu mulai dengan tabel yang lebih kecil (variabel). Itu rumit dengan pandangan meskipun ...

    SELECT  -- lots of fields
    FROM    @LocationIds [b] WITH (NOEXPAND)
            INNER JOIN  [dbo].[ListingSearchView][a] WITH (NOEXPAND) 
                ON [a].[LocationId] = [b].[Id]
    WHERE   [a].[StatusType] = @statusType
    OPTION (FORCE ORDER);

atau Anda bisa memaksa loop bergabung jika itu umumnya bagaimana Anda ingin bergabung dengan variabel tabel ke tampilan, yang juga akan memaksa pesanan ...

    SELECT  -- lots of fields
    FROM    @LocationIds [b] WITH (NOEXPAND)
            INNER LOOP JOIN  [dbo].[ListingSearchView][a] WITH (NOEXPAND) 
                ON [a].[LocationId] = [b].[Id]
    WHERE   [a].[StatusType] = @statusType
    --leaving this here so you don't get an annoying warning 
    OPTION (FORCE ORDER);
Jeremy Giaco
sumber
0

Tulis nama prosedur Store di Editor Kueri, lalu Pilih proc Store. name & then Pilih paket Eksekusi Tampilan Perkiraan atau Klik (Ctrl + L). di bawah gambar ini.

Gambar Tampilan Perkiraan rencana Eksekusi

kemudian rencana Eksekusi muncul tepat di sebelah Tab Pesan di bagian bawah Editor Kueri. kemudian di garis warna hijau menunjukkan rincian Indeks yang hilang dan klik kanan itu. Kemudian Query baru terbuka di tab baru kemudian buat INDEX. maka Permintaan Anda berjalan cepat.

Jadi saya menggunakan metode ini untuk Mendiagnosis Permintaan yang bekerja lambat. dan juga ada begitu banyak permintaan atau metode yang dapat Anda gunakan.

Rencana eksekusi dengan detail

rks_dotnet
sumber
-1

Jika Anda pikir masalahnya ada dalam pemblokiran, saya akan menyarankan Anda untuk menggunakan tingkat isolasi transaksi yang optimis Baca Snapshot Komitmen (ingat bahwa ini akan membuat overhead pada tempDB Anda).

REFERENSI: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/snapshot-isolation-in-sql-server

Jika masalahnya bukan pada pemblokiran baca / tulis, Anda dapat mencoba menambahkan indeks pada tampilan Anda (pilihan indeks terbaik tergantung pada selektivitas data Anda)

CREATE NONCLUSTERED INDEX IX_ListingSearchView (LocationID, StatusType) INCLUDE (other columns...)
Artashes Khachatryan
sumber
1
Indeks yang Anda sarankan sudah ada IX_ListingSearchView_ForAPI(lihat skrip dalam pertanyaan).
Paul White mengatakan GoFundMonica
1
Hai, terima kasih atas jawaban Anda. Seperti yang saya katakan dalam pertanyaan saya, saya ingin tahu apa masalahnya sebelum saya menerapkan perbaikan. Kalau tidak, saya hanya bisa menghadap masalah sebenarnya. Pertanyaan saya adalah tentang menemukan masalah terlebih dahulu, kemudian solusi yang benar.
RPM1984
Bisakah Anda mendapatkan permintaan lambat di lingkungan lokal Anda? Jika kueri yang sama kadang-kadang berjalan lambat dan kadang-kadang berjalan cepat mungkin tergantung pada parameter input. Bisakah Anda memberikan jumlah bacaan logis dan jumlah baris yang dikembalikan oleh permintaan lambat Anda.
Artashes Khachatryan
@ ArthesKhachatryan ya, terkadang berjalan lambat di lokal juga. Saya telah memperbarui pertanyaan dengan rencana eksekusi. Saya bertanya-tanya apakah ini terkait dengan permintaan lambat mengembalikan lebih banyak baris daripada yang cepat, seperti yang Anda katakan.
RPM1984