2015-01-28 17 views
6

Ho creato un indice funzionale su una tabella di sybase.Perché Sybase non utilizza un indice funzionale?

create index acadress_codpost_lower on acadress(LOWER(l5_codpost)) 

Ho poi esegue una query complessa che utilizza l'indice. Senza l'indice ci vogliono 17.086 secondi. Con l'indice ci vogliono 0,076 secondi.

L'ho eseguito da due diversi client SQL e su entrambi i server Sybase di sviluppo e pre-produzione. In tutti i casi vedo l'accelerazione dall'indice.

Tuttavia, quando eseguiamo una query identica da Java (e so che è identica da quando ho registrato l'SQL generato e l'ho usata direttamente nei client SQL), le prestazioni sono esattamente le stesse di prima che abbiamo aggiunto gli indici.

Quale possibile motivo potrebbe esserci per le query SQL identiche per utilizzare l'indice quando eseguito da ACE e SQuirreL ma non da Java?

Il mio primo pensiero è che forse Sybase stia memorizzando nella cache i piani di esecuzione per le dichiarazioni preparate e non usando l'indice. Abbiamo provato a riavviare il server Java diverse volte (altri servizi utilizzano il server Sybase quindi è più difficile rimbalzare) e non ha fatto alcuna differenza.

L'altra possibilità è che stiamo usando una versione molto vecchia del driver Sybase:

jConnect (TM) for JDBC(TM)/7.00(Build 26502)/P/EBF17993/JDK16/Thu Jun 3 3:09:09 2010 

E 'possibile che gli indici funzionali non sono supportati da questa versione di JConnect?

Qualcuno sa se una di queste teorie potrebbe essere corretta o se c'è qualcos'altro che ho perso?

+1

Forse rilevante: [istruzione cache] (http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc31644.1570/html/sag2/CHDHGEFE.htm) Che cosa esatto hai la versione di Sybase? E le domande sono identiche? (Solo un ipotesi, la cache di dichiarazione può essere case sensitive) –

+1

vedono anche questi suggerimenti: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc00967.1550/html /MigrationGuide/MigrationGuide14.htm –

+0

Quanto sono identiche le query degli "altri" sistemi rispetto alla query basata su Java? Anche l'istruzione preparata può essere il problema, uno dei valori è parametrizzato? Un buon test da fare sarebbe quello di estrarre l'SQL identico che viene eseguito dalla console e inserirlo in una normale istruzione JDBC da Java ed eseguirlo "così com'è". – rolfl

risposta

1

Ho esaminato questo e quello per la settimana scorsa o così e mentre ancora non ho una risposta definitiva ho una teoria plausibile.

Ho provato i suggerimenti dai commenti e grazie a loro che ero in grado di restringere la causa fino a un singolo cambiamento, se ho la query:

"where LOWER(aca.l5_codpost) like '"+StringEscapeUtils.escapeSql("NG179GT".toLowerCase())+"'" 

Poi la query utilizza l'indice e ritorna estremamente velocemente.

Se d'altra parte ho:

where LOWER(aca.l5_codpost) like :postcode 

query.setString("postcode", "NG179GT".toLowerCase()); 

allora non utilizzare l'indice.

La teoria è che Sybase sta ottimizzando il piano di query senza informazioni sul contenuto di :postcode, quindi non sta utilizzando l'indice. Non ricompila la query una volta che conosce il contenuto in modo che non usi mai l'indice.

Ho provato a forzare l'indice utilizzando (index acadress_codpost_lower) e questo non ha fatto alcuna differenza.

Ho provato set forceplan off e set literal_autoparam off e nessuno ha fatto alcuna differenza.

L'unica cosa che posso trovare che modifica il comportamento è incorporare direttamente l'opzione nel piano di query o averlo come parametro.

Così il lavoro intorno è incorporare il parametro nella stringa di query, anche se mi piace ancora di sapere cosa sta realmente accadendo e risolvere il problema in modo corretto.