Czy istnieje sposób na zmuszenie indeksu do pozostania w pamięci w SQL Server 2008?

10

Mam tabelę z kilkoma milionami wierszy, z której od czasu do czasu muszę uruchamiać zapytania. Pierwsze zapytanie zwykle będzie dość wolne (około 10s), a kolejne zapytania są zwykle znacznie szybsze (około 1s). Po kilku godzinach ponownie rozpoczyna się powolny / potem szybki cykl.

Sprawdziłem w moim planie wykonania, czy wszystkie potrzebne indeksy były obecne i odpowiednio używane, i zakładam, że różnica w wydajności wynika z faktu, że indeks jest rzeczywiście w pamięci dla kolejnych zapytań (czy mam rację, czy są inne Możliwe przyczyny?)

Korzystam również z wielu innych zapytań, używając indeksów, ale te zapytania są mniej czasochłonne, a ich wydajność jest mniej krytyczna, więc obawiam się, że te indeksy wypychają mój indeks krytyczny z pamięci podręcznej pamięci.

Oprócz oczywistej poprawki „dodaj więcej pamięci RAM”, zastanawiałem się nad skryptami, które będą uruchamiane co godzinę w celu wymuszenia powrotu indeksu do pamięci.

Czy jest na to bardziej elegancki sposób? Jak sposób na wskazanie SQLServerowi, że jeśli ma tylko wystarczającą ilość pamięci do przechowywania jednego indeksu w pamięci podręcznej, powinien to być ten?

Wiem, że zazwyczaj najlepszą rzeczą jest nie zepsuć SQLServer w odniesieniu do tego rodzaju rzeczy, ale niezwykła natura mojego zapytania (działa bardzo rzadko, ale ma krytyczne znaczenie czasowe) sprawia, że ​​uważam, że miałoby to sens (jeśli to możliwe) .

Jestem również ciekawy, czy istnieje sposób, aby wiedzieć, które indeksy są buforowane w pamięci w danym momencie?

Brann
źródło

Odpowiedzi:

13

Kiedyś było DBCC PINTABLEpolecenie, ale uważam, że przestało działać w wersji 6.5, a może 7.0. Oświadczenie prawdopodobnie nadal sugeruje , że zadziałało, jeśli spróbujesz, ale po prostu powraca, to naprawdę nie ma możliwości.

Niestety tak naprawdę nie ma sposobu na kontrolowanie, które indeksy są przechowywane w pamięci podręcznej - najlepszym rozwiązaniem, jakie znam dla tabel, które są okresowo gorące, jest utrzymywanie ich na gorąco ręcznie (co już opisałeś w swoim pytaniu).

Które indeksy są w pamięci, możesz uzyskać ogólny pomysł sys.sm_os_buffer_descriptors. Opublikowałem poradę na ten temat:

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

Aaron Bertrand
źródło
Hmm, według tego skryptu, tabela 75 MB zajmuje 900 MB puli buforów. Czy to normalne / możliwe?
db2
1
@ db2 ile masz indeksów?
JNK
2
Także jak bardzo jest podzielony ... mierzy strony, a nie dane. Twoje strony mogą być względnie puste, co może przyczynić się do zawyżenia miary.
Aaron Bertrand
0

Spróbuj użyć wskazówekKEEPPLAN i KEEPPLAN FIXED zapytań .

KEEPPLAN zmusza optymalizator zapytań do zmniejszenia szacowanego progu ponownej kompilacji dla zapytania.

KEEPFIXED PLAN zmusza optymalizator zapytań, aby nie rekompilował zapytania z powodu zmian w statystykach. Określenie KEEPFIXED PLAN zapewnia, że ​​zapytanie zostanie ponownie skompilowane tylko wtedy, gdy schemat bazowych tabel zostanie zmieniony lub jeśli sp_recompile zostanie wykonany dla tych tabel.

StanleyJohns
źródło