Problema di stima della cardinalità sull'unione interna


13

Faccio fatica a capire perché la stima delle righe sia terribilmente sbagliata, ecco il mio caso:

Join semplice: utilizzando SQL Server 2016 sp2 (stesso problema su sp1), dbcompatiblity = 130.

select Amount_TransactionCurrency_id, CurrencyShareds.id 
from CurrencyShareds 
    INNER JOIN annexes ON Amount_TransactionCurrency_id = CurrencyShareds.Id 
option (QUERYTRACEON 3604, QUERYTRACEON 2363);

SQL stima 1 riga, mentre è 107131 e sceglie di eseguire un ciclo nidificato ( collegamento al piano ). Dopo che le statistiche sono state aggiornate su CurrencyShareds, la stima va bene e viene scelto un join unione ( collegamento al nuovo piano ). Non appena viene aggiunto un solo record a CurrencyShareds, le statistiche diventano "stantie" e sql torna alla stima errata.

Non mi preoccuperei molto di questa semplice query, ma questa è solo una parte di una più grande, e questo è l'inizio di un domino ...

Perché l'aggiunta di una riga alla tabella dei 100 record provoca un danno del genere? Quando guardo l'output della traccia della stima della cardinalità, vedo questo avviso ***WARNING: badly-formed histogram ***ma non sono riuscito a trovare altro su questo argomento.

Ecco l'output completo dalla stima della cardinalità:

Begin selectivity computation
Input tree:

LogOp_Join

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

ScaOp_Comp x_cmpEq

ScaOp_Identifier QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id

ScaOp_Identifier QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id

Plan for computation:

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1 *** WARNING: badly-formed histogram ***

Selectivity: 4.59503e-018

Stats collection generated:

CStCollJoin(ID=3, CARD=1 x_jtInner)

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

End selectivity computation

Estimating distinct count in utility function

Input stats collection:

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

Columns to distinct on:QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id

Plan for computation:

CDVCPlanLeaf

0 Multi-Column Stats, 1 Single-Column Stats, 0 Guesses

Covering multi-col stats id: 7

Using ambient cardinality 107131 to combine distinct counts:

5

Combined distinct count: 5

Result of computation: 5

Estimating distinct count in utility function

Input stats collection:

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

Columns to distinct on:QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id

Plan for computation:

CDVCPlanUniqueKey

Result of computation: 100

E quando aggiorno le statistiche su CurrencyShareds la parte con modifiche "istogramma mal formato" e la cardinalità viene calcolata correttamente

Plan for computation:

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1

Selectivity: 0.01

Stats collection generated:

CStCollJoin(ID=3, CARD=107131 x_jtInner)

CStCollBaseTable(ID=1, CARD=107131 TBL: annexes)

CStCollBaseTable(ID=2, CARD=100 TBL: CurrencyShareds)

End selectivity computation

E informazioni sulle statistiche per questo "[CurrencyShareds] .Id dalle statistiche con ID 1" con avviso sull'istogramma, che mi sembra perfetto ...

Name                                                                                                                             Updated              Rows                 Rows Sampled         Steps  Density       Average key length String Index Filter Expression                                                                                                                                                                                                                                                Unfiltered Rows      Persisted Sample Percent
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- ------------------------
PK_CurrencyShareds_Id                                                                                                            May 23 2018 10:43PM  98                   98                   75     1             8                  NO           NULL                                                                                                                                                                                                                                                             98                   0

(1 row affected)

All density   Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0,01020408    8              Id

(1 row affected)

RANGE_HI_KEY         RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
-------------------- ------------- ------------- -------------------- --------------
119762190797406464   0             1             0                    1
119762190797406466   1             1             1                    1
119762190797406468   1             1             1                    1
119762190797406470   1             1             1                    1
119762190797406472   1             1             1                    1
119762190797406474   1             1             1                    1
119762190797406476   1             1             1                    1
119762190797406478   1             1             1                    1
119762190797406480   1             1             1                    1
119762190797406482   1             1             1                    1
119762190797406484   1             1             1                    1
119762190797406486   1             1             1                    1
119762190797406488   1             1             1                    1
119762190797406490   1             1             1                    1
119762190797406492   1             1             1                    1
119762190797406494   1             1             1                    1
119762190797406496   1             1             1                    1
119762190797406498   1             1             1                    1
119762190797406500   1             1             1                    1
119762190797406502   1             1             1                    1
119762190797406504   1             1             1                    1
119762190797406506   1             1             1                    1
119762190797406507   0             1             0                    1
478531702587687680   0             1             0                    1
478531702591881728   0             1             0                    1
478531702591881729   0             1             0                    1
478531702591881984   0             1             0                    1
478531702591881985   0             1             0                    1
478531702596076032   0             1             0                    1
478531702596076033   0             1             0                    1
478531702596076288   0             1             0                    1
478531702600270336   0             1             0                    1
478531702600270592   0             1             0                    1
478532235583062528   0             1             0                    1
478532235583062784   0             1             0                    1
478532235587256832   0             1             0                    1
530792464911467264   0             1             0                    1
530792464924049920   0             1             0                    1
530792464924050176   0             1             0                    1
530792464928244224   0             1             0                    1
530792464928244480   0             1             0                    1
530792464932438528   0             1             0                    1
530792464932438784   0             1             0                    1
530792464936632832   0             1             0                    1
530792464936632833   0             1             0                    1
530792464936633088   0             1             0                    1
530792464940827136   0             1             0                    1
530792464940827392   0             1             0                    1
530792464949216000   2             1             2                    1
530792464953410048   0             1             0                    1
530792464953410304   0             1             0                    1
530792464957604352   0             1             0                    1
530792464957604353   0             1             0                    1
530792464957604608   0             1             0                    1
530792464961798656   0             1             0                    1
530792464961798912   0             1             0                    1
530792464965992960   0             1             0                    1
530792464965993216   0             1             0                    1
530792464965993217   0             1             0                    1
530792464970187264   0             1             0                    1
530792464970187265   0             1             0                    1
530792464970187520   0             1             0                    1
530792464974381568   0             1             0                    1
530792464974381824   0             1             0                    1
530792464974381825   0             1             0                    1
530792464978575872   0             1             0                    1
530792464978575873   0             1             0                    1
530792464978576128   0             1             0                    1
867420708903354880   0             1             0                    1
867420708903355136   0             1             0                    1
867420708903355137   0             1             0                    1
960876568220042240   0             1             0                    1
976385263448130048   0             1             0                    1
977302121709864192   0             1             0                    1
977955748426318592   0             1             0                    1

e informazioni per il secondo indice:

Name                                                                                                                             Updated              Rows                 Rows Sampled         Steps  Density       Average key length String Index Filter Expression                                                                                                                                                                                                                                                Unfiltered Rows      Persisted Sample Percent
-------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- ------ ------------- ------------------ ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------- ------------------------
IX_FK_Amount_TransactionCurrency                                                                                                 May 21 2018  3:29PM  107204               107204               5      0             16                 NO           NULL                                                                                                                                                                                                                                                             107204               0

(1 row affected)

All density   Average Length Columns
------------- -------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0,2           8              Amount_TransactionCurrency_id
9,32801E-06   16             Amount_TransactionCurrency_id, Id

(2 rows affected)

RANGE_HI_KEY         RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
-------------------- ------------- ------------- -------------------- --------------
119762190797406475   0             160           0                    1
119762190797406478   0             867           0                    1
119762190797406481   0             106           0                    1
119762190797406494   0             105742        0                    1
119762190797406496   0             329           0                    1

Risposte:


10

Sulla base dei tuoi istogrammi sono stato in grado di riproporre il problema nel CU6 2017. Non direi che stai facendo qualcosa di sbagliato. Piuttosto, qualcosa non va nella stima della cardinalità. Ecco cosa ottengo prima di inserire una riga:

inserisci qui la descrizione dell'immagine

La stima della cardinalità finale cade un po 'dopo aver inserito una riga:

inserisci qui la descrizione dell'immagine

Qui hai una riproduzione piuttosto semplice, quindi il mio consiglio è di inviare un feedback sul prodotto o di aprire un ticket di supporto con Microsoft. Sono stato in grado di trovare alcune soluzioni alternative che hanno funzionato sui dati di esempio e uno dei potrebbe essere accettabile per te.

  1. Rilascia l'indice univoco CurrencyShareds.Id. Non riesco a far funzionare la riproduzione senza un indice univoco. La tabella è piccola, quindi forse puoi cavartela senza l'indice. Certo, potresti avere ottime ragioni per mantenerlo.
  2. Materializza i risultati del join in una tabella temporanea. In base alla tua domanda è importante ottenere una stima ragionevole in questo passaggio in modo che la query più grande funzioni bene. Una tabella temporanea è un modo per farlo accadere.
  3. Utilizzare il CE legacy. Non riesco a riprodurre il problema con esso. Naturalmente, ciò potrebbe avere conseguenze negative sul resto della query.
  4. Ingannare Query Optimizer con codice stupido. Ad esempio, nei miei test la seguente riscrittura funziona alla grande:

.

select Amount_TransactionCurrency_id, CurrencyShareds.id
from CurrencyShareds 
INNER JOIN annexes
ON Amount_TransactionCurrency_id % 9223372036854775809 = CurrencyShareds.Id % 9223372036854775809

Sospetto che ciò funzioni perché la CE sembra utilizzare la densità anziché l'istogramma. Altre riscritture simili possono avere lo stesso effetto. Non è garantito che il tipo di query continuerà a funzionare bene in futuro. Ecco perché dovresti contattare Microsoft per migliorare le probabilità che un giorno una soluzione per il tuo problema lo trasformi nel prodotto rilasciato.


8

Ok, spero di capirlo ora - quindi questo è il nostro caso

Dato

  1. Una tabella di riferimento (CurrencyShareds) con ~ 100 righe, ma gli ID sono grandi e i valori min e max differiscono molto - min: 119.762.190.797.406.464 vs max: 977.955.748.426.318.592
  2. Una tabella (Allegati) che ha un semplice FK per CurrencyShared, ma vengono utilizzate solo poche valute - puoi vedere che l'istogramma per IX_FK_Amount_TransactionCurrency elenca 5 ID - e ciò che è importante solo quegli ID "bassi", poiché altri non vengono utilizzati.

Quando tutte le statistiche sono aggiornate allora

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1

Selectivity: 0.01

Quindi la selettività calcolata per il join va bene, come 100 * 107.131 * 0,01 = 107.131

Quando le statistiche per i curriculum condivisi non sono aggiornate, allora

CSelCalcExpressionComparedToExpression( QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id x_cmpEq QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id )

Loaded histogram for column QCOL: [test.MasterData].[dbo].[Annexes].Amount_TransactionCurrency_id from stats with id 7

Loaded histogram for column QCOL: [test.MasterData].[dbo].[CurrencyShareds].Id from stats with id 1 *** WARNING: badly-formed histogram ***

Selectivity: 4.59503e-018

La selettività diminuisce drasticamente, quindi il numero di riga stimato del join è 1.

Quando l'istogramma cambia

Dopo aver aggiunto una singola riga agli allegati che fa riferimento a CurrencyShared con ID alto, quindi l'istogramma di IX_FK_Amount_TransactionCurrency cambia in

RANGE_HI_KEY         RANGE_ROWS    EQ_ROWS       DISTINCT_RANGE_ROWS  AVG_RANGE_ROWS
-------------------- ------------- ------------- -------------------- --------------
119762190797406475   0             173           0                    1
119762190797406478   0             868           0                    1
119762190797406481   0             107           0                    1
119762190797406494   0             105745        0                    1
119762190797406496   0             330           0                    1
119762190797406618   0             1             0                    1
119762190797406628   0             1             0                    1
977955748426318623   0             1             0                    1

Con questo istogramma il problema scompare, ora l'aggiunta di una nuova riga ai curriculum condivisi non provoca un drastico calo della stima della cardinalità.

Perché?

Ho il sospetto che l'algoritmo di stima dell'istogramma approssimativo funzioni in sql2014 + e sto basando la mia ipotesi su questo fantastico post https://www.sqlshack.com/join-estimation-internals/

La stima dell'istogramma approssimativo è un nuovo algoritmo e meno documentato, anche in termini di concetti generali. È noto che invece di allineare gli istogrammi passo dopo passo, li allinea con solo i limiti minimo e massimo dell'istogramma. Questo metodo introduce potenzialmente meno errori CE (non sempre, tuttavia, perché ricordiamo che questo è solo un modello).

Giusto per chiarire tutto - perché abbiamo ID così strani nei curriculum condivisi?

È abbastanza semplice: i nostri ID sono globalmente unici e si basano in parte sul timestamp (implementazione basata sul fiocco di neve ). Le valute più comuni sono state aggiunte all'inizio dell'applicazione diversi anni fa e solo quelle poche sono realmente utilizzate nella produzione, ecco perché nell'istogramma ci sono solo quelle con ID "basso".

Il problema è emerso nei nostri ambienti di test, in cui alcuni test automatici hanno iniziato ad aggiungere valute di test, causando l'esecuzione di alcune query più a lungo o il timeout ...

Come risolvere il problema?

Aggiorneremo le statistiche per quelle tabelle di riferimento (potremmo avere un problema simile con altre tabelle di dati di riferimento simili) più spesso - quelle tabelle sono piccole quindi l'aggiornamento delle statistiche non è un problema

Lezioni imparate

  • Le statistiche aggiornate sono importanti !!!
  • la semplice vecchia colonna di identità non causerebbe questi problemi :)

Per quanto riguarda l'allineamento approssimativo
Paul White 9
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.