2013-01-02 2 views
19

Sembra che count (*) sia più lento di NUM_ROWS. Gli esperti in quest'area possono far luce su questo.Numero di righe Oracle per tabella (*) rispetto a NUM_ROWS da DBA_TABLES

+7

num_rows è una statistica che potrebbe non essere aggiornata. se hai bisogno del conteggio effettivo allora dovresti andare contro il tavolo stesso con un conteggio (*) – Randy

+0

Non l'ho testato, ma ho letto da qualche parte che 'count (1)' è più veloce di 'count (*)'. –

+6

@Paul Tomblin - c'è stata una lunga discussione su Ask Tom che ha ridimensionato questa idea. è lo stesso. – Randy

risposta

16

1) Ottenere NUM_ROWS dalla query seguente significa che il valore no.of delle righe viene aggiornato da DBMS_STATS. Quindi non contiene il numero corrente di righe nella tabella ma un'approssimazione calcolata l'ultima volta che è stato eseguito DBMS_STATS.

SELECT table_name, 
     num_rows 
    FROM dba_tables 
WHERE TABLE_NAME='NAME' 

per aggiornare il valore di conteggio riga nella visualizzazione DBA_TABLES eseguire

exec dbms_stats.gather_schema_stats(ownname => 'NAME'); 

2) count (*) invoca un calcolo di n. di righe dalla tabella.

+2

Per vedere quanto sono fresche le statistiche, aggiungi ' LAST_ANALYZED' alla richiesta. –

+0

E 'num_rows' può essere una stima, non il numero esatto, specialmente se non si specifica il parametro' estimate_percent' della chiamata a gather_schema_stats. –

18

Secondo the documentation NUM_ROWS è il "Numero di righe nella tabella", così posso vedere come questo potrebbe essere fonte di confusione. Lì, tuttavia, c'è una grande differenza tra questi due metodi.

Questa query seleziona il numero di righe in MY_TABLE da una vista di sistema. Si tratta di dati che Oracle ha precedentemente raccolto e archiviato.

select num_rows from all_tables where table_name = 'MY_TABLE' 

Questa query conta il numero corrente di righe in MY_TABLE

select count(*) from my_table 

Per definizione sono pezzi di differenza di dati. Ci sono due ulteriori informazioni necessarie su NUM_ROWS.

  1. Nella documentazione c'è un asterisco dal nome della colonna, che porta a questa nota:

    Colonne contrassegnati con un asterisco (*) sono popolati solo se si raccolgono statistiche sul tavolo con l'istruzione ANALYZE o il pacchetto DBMS_STATS .

    Ciò significa che, a meno che non siano state raccolte statistiche sulla tabella, questa colonna non avrà alcun dato.

  2. Le statistiche raccolte in 11g + con il valore predefinito estimate_percent o con una stima del 100% restituiscono un numero preciso per quel punto nel tempo. Tuttavia, le statistiche raccolte prima di 11g o con un numero personalizzato estimate_percent inferiore al 100%, utilizzano il campionamento dinamico e potrebbero non essere corrette. Se accumuli il 99,999%, una singola riga può essere ignorata, il che significa che la risposta che ottieni non è corretta.

Se la tabella è mai aggiornamento, allora è certamente possibile utilizzare ALL_TABLES.NUM_ROWS per scoprire il numero di righe in una tabella. Tuttavia,, ed è un grande tuttavia, se qualsiasi processo inserisce o cancella le righe dalla tua tabella sarà nel migliore dei casi una buona approssimazione e, a seconda se il database raccoglie automaticamente le statistiche potrebbe essere terribilmente sbagliato.

In generale, è sempre meglio contare il numero di righe nella tabella piuttosto che fare affidamento sulle tabelle di sistema.