ELIMINA semplice, ma piano di esecuzione complicato


9

Quando eseguo questa eliminazione:

DELETE FROM ETLHeaders WHERE ETLHeaderID < 32465870

... cancella 39.157 righe. Dovrebbe essere semplice perché sta eliminando su ETLHeaderID che è l'indice cluster e la chiave primaria. Ma (secondo il piano di esecuzione) sembra colpire 361.190 righe e usare altri indici. La tabella ha un campo con un tipo di dati XML (nel caso in cui questo venga eliminato).

Qualche idea sul perché e come posso accelerare questo ELIMINARE?

Piano di esecuzione qui: http://sharetext.org/qwDY Schema della tabella qui: http://sharetext.org/Vl9j

Grazie

Risposte:


10

I livelli principali del piano riguardano la rimozione delle righe dalla tabella di base (l'indice cluster) e il mantenimento di quattro indici non cluster. Due di questi indici vengono mantenuti riga per riga contemporaneamente all'elaborazione delle eliminazioni degli indici cluster. Questi sono i "+2 indici non cluster" evidenziati in verde di seguito.

Per gli altri due indici non cluster, l'ottimizzatore ha deciso che è meglio salvare le chiavi di questi indici su un tavolo di lavoro tempdb (l'Eager Spool), quindi riprodurre lo spool due volte, ordinandolo per i tasti indice per promuovere un modello di accesso sequenziale.

Manutenzione periodica dell'indice

La sequenza finale delle operazioni riguarda il mantenimento degli xmlindici primario e secondario , che non sono stati inclusi nello script DDL:

Manutenzione dell'indice XML

Non c'è molto da fare al riguardo. Gli indici e gli xmlindici non cluster devono essere mantenuti sincronizzati con i dati nella tabella di base. Il costo di gestione di tali indici fa parte del compromesso che si effettua quando si creano indici aggiuntivi su una tabella.

Detto questo, gli xmlindici sono particolarmente problematici. È molto difficile per l'ottimizzatore valutare con precisione quante righe si qualificheranno in questa situazione. In realtà, sopravvaluta enormemente per l' xmlindice, determinando la concessione di quasi 12 GB di memoria per questa query (anche se al momento dell'esecuzione vengono utilizzati solo 28 MB):

Conteggio delle righe stimato

È possibile prendere in considerazione l'esecuzione dell'eliminazione in batch più piccoli, sperando di ridurre l'impatto dell'eccessiva concessione di memoria.

È inoltre possibile testare le prestazioni di un piano senza l'utilizzo di sorta OPTION (QUERYTRACEON 8795). Questo è un flag di traccia non documentato, quindi dovresti provarlo solo su un sistema di sviluppo o test, mai in produzione. Se il piano risultante è molto più veloce, è possibile acquisire l'XML del piano e utilizzarlo per creare una guida di piano per la query di produzione.


3

Sei sulla strada giusta: l'indice XML è il problema. Ovviamente, esiste un indice XML primario e secondario.

Quando si esegue un DELETE sulla tabella di base (ETLHeaders), anche i dati devono essere eliminati da ogni indice di questa tabella. Questo sovraccarico può essere significativo, soprattutto per gli indici XML.

L'indice che causa la lunga durata è l'indice XML secondario [XML_IX_ETLHeaders_Property]. Le 39.157 righe nella "tabella relazionale" si riferiscono a 361.190 righe nell'indice XML primario [XML_IX_ETLHeaders]. E quelle 361k righe devono essere ordinate per poter essere utilizzate per eliminare l'indice secondario. E questa operazione di ordinamento sta causando la lunga durata della query. (Come nota a margine, le statistiche dell'indice di entrambi gli indici xml sembrano essere molto lontane: la dimensione effettiva dei dati delle 361k righe dell'indice xml primario è di 160 MB mentre la dimensione stimata dei dati è di quasi 4 TB (sì, 4 TerraByte !!)) .

L'unica opzione che vedo per velocizzare questa query è eliminare l'indice XML secondario. A seconda dei dati potrebbe essere un'opzione migliore per distruggere i dati XML in una tabella relazionale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.