2013-11-22 12 views
6

Używam programu SQL Server 2008 i odmawia wykonania wyszukiwania w moim indeksie, który obejmuje kolumnę obliczoną.Dlaczego SQL Server nie wykonuje wyszukiwania indeksu przy użyciu mojej kolumny obliczeniowej

Moja tabela wygląda następująco:

CREATE TABLE Person 
{ 
    Id uniqueidentifier NOT NULL, 
    InsertDate datetime NOT NULL, 
    PhoneNumber NULL, 
    PhoneNumberComparable AS (MakePhoneNumberComparable(PhoneNumber)) PERSISTED, 
    ... etc... 
} 

Jest klastrowany klucz podstawowy indeks na kolumnie ID, a także indeks na kolumnie InsertDate.

Istnieje indeks na kolumnie PhoneNumberComparable obliczonej w ten sposób:

CREATE NONCLUSTERED INDEX IX_Person_PhoneNumberComparable ON Person 
(
    PhoneNumberComparable ASC 
) 

Indeksy mają do aktualnych statystyk.

Moja kwerenda wygląda następująco:

SELECT TOP 20 * FROM Person 
WHERE PhoneNumberComparable = @PhoneNumber 
ORDER BY InsertDate DESC 

Domyślnie SQL Server zdecyduje się użyć indeksu na InsertDate zamiast indeksu PhoneNumberComparable, powodując bardzo słabe wyniki.

Jeśli spróbuję wymusić użycie indeksu numeru telefonu, poprzez dodanie Z (INDEX = IX_Person_PhoneNumberComparable) do zapytania, SQL próbuje wykonać skanowanie, a nie szukać.

Gdy próbuję użyć FORCESEEK podpowiedź kwerendy, a następnie SQL Server daje mi następujący błąd:

Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.

Więc w zasadzie, z jakiegoś powodu SQL Server odmawia szukać mojego indeksu! Czemu?

EDIT

Zgodnie z sugestiami w komentarzach, ja uproszczone kwerendy, ale problem nadal istnieje (skanowanie na klucz podstawowy jest wykonywana zamiast szukać na indeksie numer telefonu):

SELECT TOP 20 PhoneNumberComparable FROM Person 
WHERE PhoneNumberComparable = @PhoneNumber 
+0

Co stanie się, gdy spadnie z zapytania zapytanie "ORDER BY InsertDate DESC"? – iruvar

+0

@ 1_CR Jeśli zrzucę ZAMÓWIENIE przez InsertDate DESC, spróbuje użyć indeksu klucza podstawowego. Taki sam problem! – cbp

+0

Ten wątek mówi o podobnym problemie co mój, co oznacza, że ​​jest to błąd w SQL Server 2008: http://www.sqlservercentral.com/Forums/Topic1085414-392-1.aspx – cbp

Odpowiedz

5

Wierzę, że to wymyśliłem.

Problem wynika z funkcji MakePhoneNumberComparable wykorzystującej inną funkcję, która znajduje się w innym schemacie. Aby rozwiązać ten problem, musiałem sklonować drugą kopię innej funkcji, ale przenieść ją pod tym samym schematem co tabela.

This article (dzięki komentarzowi Kahna) mówi, że możesz definiować indeksy tylko wtedy, gdy "Wszystkie odwołania do funkcji w kolumnie obliczeniowej mają tego samego właściciela co tabela".

No, nie tylko jest to wymóg posiadania bardzo irytujące do przestrzegania, ale dokumentacja firmy Microsoft jest bardzo mylące co najmniej:

  • Po pierwsze, mógłby utworzyć indeks. W rzeczywistości mógłbym nawet zeskanować indeks. Po prostu nie mogłem uzyskać kodu SQL, aby wykonać wyszukiwanie w indeksie.
  • Po drugie, o ile mi wiadomo, mówimy tutaj o schematach, a nie o właścicielach, ale o różnicy między tymi dwoma wciąż jestem nieco zdezorientowany.
  • Po trzecie, moja funkcja była w tym samym schemacie co mój stół - po prostu skorzystała z drugiej funkcji, która nie była w tym samym schemacie co tabela.
Powiązane problemy