2011-09-15 14 views
5

Sto lavorando ad una condizione di join tra 2 tabelle in cui una delle colonne per abbinare su è un concatenazione di valori. Devo unire la colonna A dalla tabellaA ai primi 2 caratteri della colonna B dalla tabellaB.prestazioni di confronto SQL tramite stringa vs come con jolly

Ho sviluppato 2 istruzioni diverse per gestirlo e ho provato ad analizzare le prestazioni di ciascun metodo.

Metodo 1:

ON tB.columnB like tA.columnA || '%' 

Metodo 2:

ON substr(tB.columnB,1,2) = tA.columnA 

Il piano di esecuzione di query ha molto meno passaggi utilizzando Metodo 1 rispetto al metodo 2, tuttavia, sembra che il metodo 2 esegue molto Più veloce. Inoltre, il piano di esecuzione mostra un indice consigliato per il Metodo 2 che potrebbe migliorare le sue prestazioni.

Lo sto eseguendo su un IBM iSeries, anche se sarebbe interessato alle risposte in senso generale per saperne di più sull'ottimizzazione delle query SQL.

Ha senso che il metodo 2 sarebbe eseguire più velocemente?

Questa domanda SO è simile, ma sembra che nessuno abbia fornito risposte concrete alla differenza di prestazioni di questi approcci: T-SQL speed comparison between LEFT() vs. LIKE operator.

PS: il design della tabella che richiede questo tipo di join non è qualcosa che posso essere modificato in questo momento. Mi rendo conto che avere i campi separati che contengono diversi tipi di dati sarebbe preferibile.

+0

INNER o OUTER JOIN? –

+0

Si tratta di un join interno. Unire il tipo può fare la differenza? – Swoop

+1

Beh, probabilmente è una partita persa per indovinare cosa sta succedendo in un Query Optimizer. Ma sì, in questo caso, se si tratta di un metodo JOIN INNER 1, è necessario leggere tutti i tA mentre il metodo 2 deve solo leggere tB. A seconda del numero di righe, ciò potrebbe essere significativo e potrebbe influire sul piano di esecuzione. –

risposta

0

Ho trovato questo riferimento in un Redbook IBM relativa a prestazioni di SQL. Sembra che la funzione scalare SUBSTR possa essere gestita in modo ottimizzato da un iSeries.

Se si cerca il primo carattere e si desidera utilizzare lo SQE invece del CQE, è possibile utilizzare la funzione di sottostringa scalare sul segno sinistra del segno di uguale. Se è necessario cercare caratteri aggiuntivi nella stringa , è possibile utilizzare anche la funzione scalare POSSTR. Con suddividere il predicato LIKE in diverse funzioni scalari, è possibile influenzare Query Optimizer per utilizzare lo SQE.

http://publib-b.boulder.ibm.com/abstracts/sg246654.html?Open

2

Sì, Metodo 2 sarebbe più veloce. LIKE non è una funzione efficiente.

di comparare le prestazioni di varie tecniche, provare utilizzando Visual Spiegate. Lo troverai sepolto in System i Navigator. Sotto la connessione di sistema, espandi database, quindi fai clic sul tuo nome RDB. Nel riquadro in basso a destra è quindi possibile fare clic sull'opzione per eseguire uno script SQL. Inserisci la tua istruzione SELECT e scegli l'opzione di menu per Visual Explain o Run and Explain. La spiegazione visiva suddividerà il piano di esecuzione della tua dichiarazione e ti mostrerà il costo per ogni parte stimata sulle tue tabelle con gli indici disponibili.

+0

Ho utilizzato Visual Explain per ottimizzare le mie query, ma sto ancora cercando di imparare come sfruttare al meglio questo strumento. Conosci qualche documentazione avanzata per questo? Finora le mie ricerche su google hanno trovato solo Mi piace di base, come caricare Visual Explain. – Swoop

+0

LIKE può essere abbastanza efficiente se il carattere jolly si trova alla fine della stringa di confronto e il motore comprende di utilizzare un indice disponibile per il confronto. –

+0

@Larry stai dicendo che in alcune circostanze l'ottimizzatore potrebbe capire che un carattere jolly alla fine equivale a LEFT()? Potete fornire qualche esempio dove sarebbe più efficiente? – WarrenT

2

Ho eseguito il seguente nel Advisor SQL in IBM Data Studio su uno dei tavoli del mio DB2 LUW 10.1 database:

SELECT * 
FROM PDM.DB30 
WHERE DB30_SYSTEM_ID = 'XXX' 
    AND DB30_VERSION_ID = 'YYY' 
    AND SUBSTR(DB30_REL_TABLE_NM, 1, 4) = 'ZZZZ' 

e

SELECT * 
FROM PDM.DB30 
WHERE DB30_SYSTEM_ID = 'XXX' 
    AND DB30_VERSION_ID = 'YYY' 
    AND DB30_REL_TABLE_NM LIKE 'ZZZZ%' 

Entrambi avevano il percorso stesso accesso esatto utilizzando lo stesso indice, lo stesso costo IO stimato e la stessa cardinalità stimata, l'unica differenza è la stima del totale della CPU il costo per il LIKE era 178.343.75 mentre il SUBSTR era 197.518.48 (differenza del ~ 10%).

Il costo totale cumulativo per entrambi era lo stesso, quindi questa differenza è trascurabile come da consulente.

0

In realtà è possibile eseguire con esempi reali nel database.

LIKE è sempre meglio alla mia corsa.

select count(*) from u_log where log_text like 'AUT%'; 
1 row(s) returned : 90ms taken 

select count(*) from u_log where substr(log_text,1,3)='AUT'; 
1 row(s) returned : 493ms taken 
Problemi correlati