Mesin SQL Server 2005 identik (?); permintaan mengambil 2sec pada satu, 15 menit pada yang lain

12

Lingkungan:

Kami memiliki dua mesin Windows Server 2003 R2 32-bit yang menjalankan SQL Server 2005. Konfigurasi perangkat keras adalah server yang identik dengan CPU Xeon 5160, RAM 4GB, dan 13GB RAID0. Bendera AWE dan / 3GB tidak diaktifkan.

Server-server diatur berdampingan menggunakan daftar periksa instalasi yang telah ditentukan, dan SEMUA perangkat lunak yang diinstal sama di kedua mesin.

Setiap pengaturan instalasi SQL server dan tingkat tambalan yang kita ketahui untuk diperiksa identik. Salah satu perbedaannya adalah bahwa TEMPDB adalah 400MB pada mesin cepat, dan 1.2GB pada mesin lambat. Namun, dalam kedua kasus, kami tidak melihat alokasi TEMPDB terjadi.

Masalah:

Ada prosedur tersimpan yang berjalan dalam 2 detik pada satu, tetapi 15 menit pada yang lain. Selama 15 menit tambahan, ada sedikit atau tidak ada aktivitas disk, tidak ada perubahan penggunaan memori, tetapi satu inti CPU disematkan pada 100% sepanjang waktu.

Perilaku ini tetap ada bahkan ketika database didukung dari satu dan dikembalikan ke yang lain.

Karena ini adalah prosedur tersimpan, monitor aktivitas dan profiler tidak menunjukkan kepada kami detail tentang di mana dalam prosedur tersimpan, aktivitas CPU tinggi ini terjadi.

Pertanyaan:

Apa lagi yang harus kita perhatikan?

Mengikuti:

Kelambatan terjadi dalam pernyataan FETCH BERIKUTNYA untuk definisi kursor berikut:

DECLARE C CURSOR FOR
    SELECT X, Y
    FROM dbo.A
    WHERE X NOT IN (SELECT X FROM dbo.B)
    AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...

Setiap pernyataan FETCH - di atas meja yang hanya berisi sekitar 1000 baris - membutuhkan sekitar 7,25 menit. (Tidak, saya tidak tahu mengapa ia melakukan dua berturut-turut, perlu bertanya kepada pengembang, tetapi itu berjalan dengan benar di kedua server).

Saya sedikit curiga dengan "TIDAK DI (PILIH ...)", karena sepertinya Baca Virtual benar-benar tinggi.

Ryandenki
sumber
Bagaimana catatan di dbo.B dan apakah dbo.BX diindeks?
Mark Storey-Smith
1
Saya ingin tahu apakah akan ada perbedaan kinerja jika Anda pergi dengan ini: pilih dbo.ax, dbo.ay dari dbo.a kiri luar gabung dbo.b di dbo.ax = dbo.bx di mana dbo.bx adalah nol dan z <= 0
DForck42
Satu lagi pemikiran untuk melempar campuran. Apakah Anda yakin pelambatannya disebabkan oleh pengambilan kursor? Apakah Anda menentukan ini dari rencana eksekusi (yang semuanya tentang perkiraan) atau dari jejak profil?
Mark Storey-Smith
Itu dari jejak profil.
ryandenki
Apakah rencana pelaksanaannya sama? Mungkin saja salah satunya menggunakan rencana eksekusi yang buruk.
Zane

Jawaban:

7

Menggunakan metodologi pemecahan masalah kinerja seperti Tunggu dan Antrian mengidentifikasi alasan untuk konsumsi CPU yang tinggi, maka tindakan yang tepat dapat direkomendasikan setelah kemacetan diidentifikasi.

Remus Rusanu
sumber
6

SQL Server memilih paket berbeda di kotak lain.

Mengembalikan biasanya akan menghapus masalah berdasarkan statistik, jadi saya akan melihat perbedaan server.

Beberapa cek kasar pertama. Jangan berasumsi: periksa

  • Periksa bahwa pengaturan SQL Server adalah sama di konfigurasi sys.conf misalnya misalnya Max derajat atau paralelisme
  • Jalankan DBCC USEROPTIONS untuk melihat apakah ada pengaturan ANSI yang berbeda pada saat dijalankan (pengaturan ANS dapat memengaruhi paket yang dipilih)
  • Periksa log Windows dan SQL Server untuk melihat apakah ada masalah

Kemudian lompati ujung yang dalam, sesuai jawaban Remus.

gbn
sumber
Terima kasih atas petunjuknya. Konfigurasi sys.configuration dan DBCC USER identik antara kedua mesin. Tidak ada kesalahan atau peringatan di log server Windows atau SQL.
1
Dan mereka juga menjalankan tata letak basis data yang identik? Tidak ada rencana admin melakukan optimasi pada (indeks membangun kembali dll.), Database memiliki statistik yang sama untuk objek yang relevan dan tata letak disk yang sama? Level tambalan yang sama?
TomTom
Ya, disk, tata letak DB, dan tingkat tambalan yang sama. Bahkan, database pada mesin cepat adalah cadangan yang dipulihkan dari mesin lambat. Dan tidak ada rencana admin yang bervariasi, sejauh yang saya bisa lihat.
ryandenki
6

Jika semua hal lain sama, kemungkinan (sesuai jawaban @ gbn) bahwa rencana eksekusi yang berbeda dihasilkan pada setiap server. Sebagai latihan akademis, akan menarik untuk melihat kedua paket tersebut jadi ambil dari cache paket di setiap server dan tambahkan ke pertanyaan Anda jika memungkinkan. Kami kemudian dapat mengidentifikasi perbedaan dalam rencana yang menyebabkan variasi besar dalam kinerja.

Untuk perbaikan cepat, lihat petunjuk USE PLAN . Ini memungkinkan untuk melampirkan paket bagus dari server cepat, ke prosedur tersimpan di server lambat.

Sunting: Mengikuti pembaruan ulang: kursor

Satu variasi lain pada kueri Anda untuk mencoba yang tidak saya lihat disebutkan dalam jawaban lain:

DECLARE C CURSOR FOR
    SELECT X, Y
    FROM dbo.A
    WHERE NOT EXISTS (SELECT 1 FROM dbo.B WHERE dbo.B.X = dbo.A.X)
    AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
Mark Storey-Smith
sumber
Ini saran yang bagus, kami sedang memeriksa rencana kueri. Sebenarnya, perlambatan dalam prosedur yang tersimpan tampaknya terkait dengan kursor. Lihat edit.
ryandenki
4

Humor saya, dan coba ganti:

DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0

dengan ini:

DECLARE C CURSOR FOR
SELECT 
    X, 
    Y
FROM dbo.A

    LEFT OUTER JOIN dbo.B
        ON dbo.A.X = dbo.b.X

WHERE dbo.B.X IS NULL
AND Z <=0

Saya tidak berpikir ini harus memanifestasikan dirinya sebagai masalah kinerja di bagian FETCH BERIKUTNYA DARI kode Anda, tapi saya belum mendapatkan injeksi kafein saya. Cobalah saran saya, dan beri tahu saya.

Semoga ini membantu,

Mat

Matt M
sumber
4

Periksa indeks Anda dan perbarui semua statistik Anda. Saya punya masalah yang sangat mirip dan ternyata statistik pada satu mesin tidak bagus.

DForck42
sumber
1

Saya telah mengalami perilaku yang sama ini dua kali dan saya akan memberi tahu Anda apa yang diperbaiki setiap kali:

1.) Saya menambahkan petunjuk DENGAN RECOMPILE ke prosedur tersimpan karena rencana cache itu mengerikan.

2.) Saya mengubah prosedur tersimpan untuk menggunakan tabel sementara, bukan variabel tabel.

Saya harap salah satu dari bantuan itu. Semoga berhasil.

Jon
sumber