2013-11-22 15 views
6

Sto utilizzando SQL Server 2008 e si rifiuta di eseguire una ricerca sul mio indice che copre una colonna calcolata.Perché SQL Server non esegue una ricerca indice utilizzando la colonna calcolata

Il mio tavolo si presenta così:

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

C'è un indice cluster chiave primaria per la colonna ID, ed anche un indice sulla colonna InsertDate.

C'è un indice sulla colonna calcolata PhoneNumberComparable come questo:

CREATE NONCLUSTERED INDEX IX_Person_PhoneNumberComparable ON Person 
(
    PhoneNumberComparable ASC 
) 

Gli indici hanno tutte statistiche aggiornate.

La mia domanda è simile al seguente:

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

Per impostazione predefinita, SQL Server decide di utilizzare l'indice su InsertDate anziché l'indice su PhoneNumberComparable, causando prestazioni molto povera.

Se si tenta di forzare l'indice del numero di telefono da utilizzare, aggiungendo WITH (INDICE = IX_Person_PhoneNumberComparable) alla query, trys SQL per eseguire una scansione anziché una ricerca.

Se provo ad utilizzare la query FORCESEEK, quindi SQL Server mi dà il seguente errore:

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.

Quindi, fondamentalmente, per qualche motivo, SQL Server si rifiuta di cercare il mio indice! Perché?

EDIT

Come per suggerimenti nei commenti, ho semplificato la query, ma il problema esiste ancora (una scansione sulla chiave primaria viene eseguita al posto di un cercare al telefono indice di numero):

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

Cosa succede quando si rilascia "ORDER BY InsertDate DESC" dalla query? – iruvar

+0

@ 1_CR Se si rilascia ORDINA DA InsertDate DESC, tenta di utilizzare l'indice della chiave primaria. Stesso problema! – cbp

+0

Questo thread parla di un problema simile al mio, il che implica che si tratta di un bug in SQL Server 2008: http://www.sqlservercentral.com/Forums/Topic1085414-392-1.aspx – cbp

risposta

5

Credo di aver capito questo.

Il problema è dovuto alla funzione MakePhoneNumberComparable che utilizza un'altra funzione che si trova in uno schema diverso. Per risolvere il problema, dovevo clonare una seconda copia dell'altra funzione, ma spostarla sotto lo stesso schema della tabella.

This article (grazie al commentatore Kahn) afferma che è possibile definire indici solo se "Tutti i riferimenti di funzione nella colonna calcolata hanno lo stesso proprietario della tabella".

Beh, non è solo questo requisito proprietà molto fastidioso per aderire, ma la documentazione di Microsoft è molto confusa a dir poco:

  • In primo luogo, ho potuto creare un indice. In effetti potrei persino scansionare l'indice. Non riuscivo a ottenere SQL per eseguire una ricerca sull'indice.
  • In secondo luogo, per quanto ne so, stiamo parlando di schemi qui, non di proprietari, ma sulla differenza tra i due sono ancora un po 'confuso.
  • In terzo luogo, la mia funzione era nello stesso schema della mia tabella: si limitava a utilizzare la seconda funzione che non era nello stesso schema della tabella.
Problemi correlati