Il rovescio della medaglia nell'utilizzo di questo stratagemma è evidente, soprattutto quando ci si trova in un ambito non più OLTP, ma di tipo data warehouse:
una stessa query, eseguita con valori diversi per le variabili di bind, potrebbe restituire poche righe in un caso e milioni di risultati in un altro: è palese che un piano di esecuzione elaborato per la prima situazione difficilmente sarà altrettanto valido per la seconda. In questo caso è d'obbligo riportare il valore del parametro
CURSOR_SHARING su
EXACT, per essere sicuri che ogni volta venga generato un nuovo piano di esecuzione potenzialmente migliore di quello utilizzato in precedenza.
La manipolazione di questo parametro non è consigliata neanche da un
guru di
Oracle come
Thomas Kyte, che illustra la problematica
in un thread:
l'utilizzo del valore FORCE, se da una parte limita il numero di hard-parse eseguiti, aumenta le operazioni di soft-parse che, sebbene meno onerose delle altre, comunque
limitano l'efficienza e la scalabilità del database; il consiglio di
Kyte è quello di utilizzare questa scorciatoia per il solo tempo necessario a modificare le applicazioni interessate, usando le
variabili di bind e riutilizzando il più possibile i cursori.
Con la versione
Oracle Database 11g, è stata aggiunta una nuova funzionalità dal nome
Adaptive Cursor Sharing; in pratica si risolve il problema del riutilizzo di un cursore - e del piano di esecuzione ad esso associato elaborato in precedenza – in presenza di valori diversi per le
variabili di bind, introducendo due nuove caratteristiche nella valutazione dei cursori stessi:
bind sensitivity e
bind awareness, ossia sensibilità e consapevolezza.
Un cursore viene marcato come
bind-sensitive quando il piano di esecuzione sia stato calcolato in base ai valori delle
variabili di bind, utilizzando il
bind variable peeking. Per cursori di questo tipo, nelle successive esecuzioni con valori diversi per le
variabili di bind, l'ottimizzatore verifica se al variare di tali valori cambia il volume dei dati manipolati dalla
query, ossia
viene valutato quanto sia selettivo il nuovo predicato rispetto al precedente: nel caso in cui questo cambiamento sia abbastanza consistente, viene generato un cursore
figlio con un piano di esecuzione, che meglio si adatta al nuovo valore assunto dalle
variabili di bind e tale nuovo cursore viene marcato come
bind-aware.
Il comportamento appena illustrato viene chiarito con degli esempi in
un post sull'argomento e nei
listati allegati ad un
articolo di Jim Czuprynski. Se a questo punto avessimo deciso di provare ad utilizzare
la nuova funzionalità offerta da Oracle, non dovremmo neanche preoccuparci di attivarla, in quanto
è già abilitata di default.