Risoluzione dei problemi relativi alle prestazioni delle query: stima della cardinalità

Query Optimizer di SQL Server è un ottimizzatore basato sui costi. Questo significa che vengono selezionati i piani di query con il minor costo di elaborazione stimato per l'esecuzione. In Query Optimizer il costo di esecuzione di un piano di query viene determinato in base a due fattori principali:

  • Numero totale di righe elaborate a ogni livello del piano di query, detto cardinalità del piano.

  • Modello di costo dell'algoritmo determinato dagli operatori utilizzati nella query.

Il primo fattore, ovvero la cardinalità, viene utilizzato come parametro di input del secondo fattore, ovvero il modello di costo. Una migliore cardinalità comporta pertanto costi stimati migliori e, di conseguenza, piani di esecuzione più rapidi.

In SQL Server SQL Server la cardinalità viene valutata principalmente sulla base di istogrammi creati al momento della creazione di indici o statistiche, in modo manuale o automatico. In alcuni casi, per determinare la cardinalità in SQL Server vengono inoltre utilizzate le informazioni sui vincoli e le riscritture logiche delle query.

Nei casi seguenti, in SQL Server non è possibile eseguire un controllo accurato delle cardinalità. Questo comporta calcoli dei costi non accurati che potrebbero portare a piani di query non ottimali. Evitando questi costrutti nelle query, è possibile migliorare le prestazioni. In alcuni casi, è possibile ricorrere a formulazioni di query alternative o ad altre misure, che vengono indicate.

  • Query con predicati che utilizzano operatori di confronto tra colonne della stessa tabella.

  • Query con predicati che utilizzano operatori e una delle seguenti condizioni è vera:

    • Non vi sono statistiche nelle colonne coinvolte a destra o a sinistra degli operatori.

    • La distribuzione dei valori nelle statistiche non è uniforme, ma la query cerca un set di valori estremamente selettivo. Questa situazione si verifica in particolare se l'operatore è diverso dall'operatore di uguaglianza (=).

    • Nel predicato viene utilizzato l'operatore di confronto diverso da (!=) o l'operatore logico NOT.

  • Le query che utilizzano qualsiasi funzione predefinita di SQL Server o una funzione definita dall'utente con valori scalari il cui argomento non è un valore costante.

  • Query che implicano il join di colonne attraverso operatori aritmetici o di concatenazione delle stringhe.

  • Query che confrontano variabili i cui valori non sono noti al momento della compilazione e dell'ottimizzazione della query.

Per cercare di migliorare le prestazioni di questi tipi di query, è possibile adottare le misure seguenti:

  • Creare statistiche o indici utili nelle colonne coinvolte nella query. Per ulteriori informazioni, vedere Progettazione di indici e Utilizzo di statistiche per migliorare le prestazioni di esecuzione delle query.

  • Utilizzare colonne calcolate e riscrivere la query nel caso in cui vengano utilizzati operatori di confronto o aritmetici per confrontare o combinare due o più colonne. La query seguente, ad esempio, consente di confrontare i valori in due colonne:

    SELECT * FROM MyTable
    WHERE MyTable.Col1 > MyTable.Col2
    

    È possibile migliorare le prestazioni aggiungendo una colonna calcolata Col3 a MyTable per calcolare la differenza tra Col1 e Col2 (Col1 meno Col2). Riscrivere quindi la query:

    SELECT * FROM MyTable
    WHERE Col3 > 0
    

    Per migliorare ulteriormente le prestazioni, creare un indice in MyTable.Col3.