6

Mam bazę danych dla wielu dzierżawców w programie SQL Server 2012, w której wiersze każdego z najemców są identyfikowane za pomocą kolumny tenant_id (inaczej: podejście Shared Database, Shared Schema). Niektórzy lokatorzy, szczególnie nowi, mają bardzo mało wierszy, podczas gdy inni mają ich wiele.Bazy danych i sniffowanie parametrów dla wielu serwerów SQL Server

Optymalizator zapytań SQL Server zwykle tworzy plan zapytań na podstawie parametrów podanych podczas pierwszego wykonania, a następnie ponownie wykorzystuje ten plan dla wszystkich przyszłych zapytań, nawet jeśli podano różne parametry. Jest to znane jako parameter sniffing.

Problem z naszą bazą danych polega na tym, że SQL Server czasami buduje te plany na podstawie parametrów wskazujących na mniejszego dzierżawcę, co działa dobrze dla tego najemcy, ale wtedy, gdy ponownie wykorzystuje buforowany plan do większego dzierżawcy, nie powiedzie się katastrofalnie (zazwyczaj w zasadzie czas). Zazwyczaj dowiadujemy się o tej sytuacji tylko wtedy, gdy jeden z naszych większych najemców kontaktuje się z nami w związku z występowaniem błędów przekroczenia limitu czasu, a następnie musimy wejść do systemu i ręcznie przepłukać wszystkie plany kwerend, aby je poprawić.

Istnieje wskazówka dotycząca kwerendy, której można użyć w celu zapobiegania buforowaniu planów zapytań SQL Server (OPTIMIZE FOR UNKNOWN), ale powoduje to dodatkowe obciążenie, ponieważ plan kwerend jest odnawiany za każdym razem, gdy wywoływane jest zapytanie. Dodatkowym problemem jest to, że używamy Entity Framework, która nie oferuje możliwości określenia podpowiedzi na temat zapytań OPTIMIZE FOR UNKNOWN.

Pytanie brzmi: jaka jest najlepsza praktyka dla baz danych dla wielu dzierżawców w odniesieniu do wąchania parametrów? Czy istnieje sposób na wyłączenie sniffingu parametrów w całej bazie danych bez konieczności określania go w każdym zapytaniu? Jeśli tak, czy to jest nawet najlepsze podejście? Czy powinienem partycjonować dane w jakiś inny sposób? Czy istnieje inne podejście, o którym nie myślę?

+0

AFAIK, musisz to zrobić za pomocą zapisanych procedur. Chyba że jest jakaś cecha EF, która może cię do tego zmusić. – RBarryYoung

+0

'OPTIMIZE FOR UNKNOWN' nie ma zachowania, które opisujesz. Mylicie to z 'OPCJĄ (REKOMPILE)). Jeśli korzystasz z wersji Enterprise Edition, możesz przejrzeć przewodniki po planach, aby podać wskazówkę. Lub istnieje flaga śledzenia (4136), aby [całkowicie wyłączyć funkcję wąchania parametrów] (http://support.microsoft.com/kb/980653), ale dotyczy to ** instancji ** nie bazy danych. –

Odpowiedz

3

miałem podobne problemy i rozwiązał go pomyślnie, przekazując swoje parametry tak:

CREATE PROCEDURE [dbo].[InsertAPCheck] 
@APBatchID int = Null, 
@BankAccountID int = Null 
AS 
    /* copy parameters to temporary variables */ 
    SELECT @xAPBatchId = APBatchId, @xBankAccountID = @BankAccountID 
. 
. 
/* now run the meat of your logic using the temp variables */ 
SELECT * FROM myTable where [email protected] 

innymi słowy, tworzenie zmiennej lokalnej na podstawie 1-1 dla każdego parametru przeszedł w a następnie tylko odwoływanie się do tych nowych zmiennych w logice SP. Prawdopodobnie brakuje mi pewnej optymalizacji, którą SQL Server mógłby zrobić dla mnie, ale co najważniejsze, tracę naprawdę okropny występ, jaki osiągam, gdy param etery wącha kopnięcia.

W twoim przypadku być może mógłbyś spróbować to tylko dla identyfikatora multi-tenant (który zakładam, że jest parametrem dla wszystkich SP?) i pozwala serwerowi SQL optymalizować pozostałe parametry, jeśli to możliwe.

+0

Jest to w zasadzie to, co robi podpowiedź zapytania OPTIMIZE FOR UNKNOWN. Niestety nie mogę użyć obu metod z Entity Framework, ponieważ nie mogę zmodyfikować generowanego zapytania. – Mike

Powiązane problemy