Apakah ada cara untuk memaksa indeks untuk tetap di memori dengan SQL Server 2008?

10

Saya punya meja dengan jutaan baris, dari mana saya perlu menjalankan beberapa query dari waktu ke waktu. Kueri pertama biasanya akan sangat lambat (sekitar 10 detik), dan kueri berikutnya biasanya lebih cepat (sekitar 1 detik). Setelah beberapa jam, siklus lambat / kemudian cepat dimulai lagi.

Saya telah memeriksa dalam rencana pelaksanaan saya bahwa semua indeks yang diperlukan ada dan digunakan dengan tepat, dan saya berasumsi perbedaan kinerja disebabkan oleh fakta bahwa indeks tersebut sebenarnya ada dalam memori untuk pertanyaan selanjutnya (apakah saya benar, atau adakah yang lain kemungkinan penyebab?)

Saya juga menjalankan banyak kueri lain menggunakan indeks juga, tetapi kueri itu kurang memakan waktu dan kinerjanya kurang kritis, jadi saya khawatir indeks itu sebenarnya mendorong indeks kritis saya keluar dari cache memori.

Terlepas dari perbaikan 'tambah lebih banyak RAM' yang jelas, saya telah memikirkan skrip query dummy untuk dijalankan setiap jam untuk memaksa indeks kembali ke memori.

Apakah ada cara yang lebih elegan untuk melakukan ini? Seperti cara untuk mengisyaratkan SQLServer bahwa jika hanya memiliki memori yang cukup untuk menyimpan satu indeks tunggal di-cache, haruskah itu?

Saya tahu bahwa biasanya hal terbaik adalah tidak mengacaukan SQLServer sehubungan dengan hal-hal semacam itu, tetapi sifat yang tidak biasa dari permintaan saya (berjalan sangat jarang, tetapi waktu-kritis) membuat saya percaya itu masuk akal (jika mungkin) .

Saya juga ingin tahu apakah ada cara untuk mengetahui indeks mana yang di-cache dalam memori pada waktu tertentu?

Brann
sumber

Jawaban:

13

Dulu ada DBCC PINTABLEperintah tetapi saya percaya bahwa berhenti bekerja di 6.5 atau mungkin 7.0. Pernyataan itu mungkin masih akan menyarankan bahwa itu berhasil jika Anda mencobanya, tetapi itu hanya kembali, itu benar-benar no-op.

Sayangnya tidak ada cara apa pun untuk mengontrol indeks mana yang disimpan dalam cache - solusi terbaik yang saya tahu untuk tabel yang secara berkala panas adalah dengan tetap membuat mereka panas secara manual (yang telah Anda jelaskan dalam pertanyaan Anda).

Untuk indeks mana yang ada dalam memori, Anda bisa mendapatkan ide kasar dari sys.sm_os_buffer_descriptors. Saya menerbitkan tip tentang ini:

http://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/

Aaron Bertrand
sumber
Hmm, menurut skrip itu, sebuah tabel 75 MB menempati 900 MB buffer pool. Apakah itu normal / mungkin?
db2
1
@ db2 berapa banyak indeks yang Anda miliki?
JNK
2
Juga seberapa terfragmentasinya ... mengukur halaman, bukan data. Halaman Anda mungkin relatif kosong, dan itu dapat berkontribusi pada ukuran yang meningkat.
Aaron Bertrand
0

Coba gunakan KEEPPLANdan KEEPPLAN FIXED permintaan petunjuk .

KEEPPLAN memaksa pengoptimal kueri untuk mengendurkan perkiraan ambang batas kompilasi ulang untuk kueri.

RENCANA KEEPFIXED memaksa pengoptimal permintaan untuk tidak mengkompilasi ulang permintaan karena perubahan dalam statistik. Menentukan KEEPFIXED PLAN memastikan bahwa kueri akan dikompilasi ulang hanya jika skema tabel yang mendasari diubah atau jika sp_recompile dijalankan terhadap tabel tersebut.

StanleyJohns
sumber