2013-01-02 4 views
19

Wygląda na to, że liczba (*) jest mniejsza niż NUM_ROWS. Czy eksperci w tej dziedzinie mogą rzucić trochę światła na to.Liczba wierszy Oracle według tabeli według liczby (*) kontra NUM_ROWS od DBA_TABLES

+7

num_rows to statystyka, która może nie być aktualna. jeśli potrzebujesz rzeczywistego liczenia, powinieneś pójść przeciwko samej tabeli z liczbą (*) – Randy

+0

Nie przetestowałem tego, ale czytałem gdzieś, że 'count (1)' jest szybsze niż 'count (*)'. –

+6

@Paul Tomblin - była obszerna dyskusja Ask Tom o tym, że obalili ten pomysł. to jest to samo. – Randy

Odpowiedz

16

1) Uzyskanie NUM_ROWS z poniższej kwerendy oznacza, że ​​żadna z wartości wierszy nie jest aktualizowana przez DBMS_STATS. Nie zawiera więc bieżącej liczby wierszy w tabeli, ale przybliżenie obliczone podczas ostatniego uruchomienia DBMS_STATS.

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

Aby zaktualizować ostatnią wartość liczby wierszy w widoku DBA_TABLES wykonać

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

2) count (*) powołuje się na wyliczenia nie. wierszy ze stołu.

+2

Aby zobaczyć, jak świeże są twoje statystyki, dodaj: LAST_ANALYZED' do zapytania o. –

+0

'' num_rows' może być wartością szacunkową, a nie dokładną, szczególnie jeśli nie określisz parametru "estimate_percent" wywołania gather_schema_stats. –

18

Zgodnie z the documentation NUM_ROWS jest "Liczba wierszy w tabeli", więc mogę zobaczyć, jak może to być mylące. Istnieje jednak zasadnicza różnica między tymi dwoma metodami.

To zapytanie wybiera liczbę wierszy w MY_TABLE z widoku systemowego. Są to dane zebrane i przechowywane przez firmę Oracle.

select num_rows from all_tables where table_name = 'MY_TABLE' 

To zapytanie zlicza aktualną liczbę wierszy w MY_TABLE

select count(*) from my_table 

Z definicji są kawałki różnicy danych. Są jeszcze dwie dodatkowe informacje o NUM_ROWS.

  1. W dokumentacji jest gwiazdka przy nazwie kolumny, co prowadzi do niniejszej noty:

    Kolumny oznaczone gwiazdką (*) są wypełniane tylko jeśli zbierać statystyk na stole instrukcja ANALYZE lub pakiet DBMS_STATS .

    Oznacza to, że jeśli nie zebrano statystyk dotyczących tabeli, ta kolumna nie będzie zawierała żadnych danych.

  2. Statystyki zebrane w 11g + z domyślną wartością estimate_percent lub ze 100% szacunkową zwrócą dokładną liczbę dla tego punktu w czasie. Jednak statystyki zebrane przed 11g lub z niestandardowym estimate_percent mniej niż 100% używa dynamicznego próbkowania i mogą być nieprawidłowe. Jeśli zbierzesz 99,999%, jeden rząd może zostać pominięty, co z kolei oznacza, że ​​otrzymana odpowiedź jest niepoprawna.

Jeśli tabela jest nigdy zaktualizowany wtedy na pewno jest możliwe użycie ALL_TABLES.NUM_ROWS aby dowiedzieć się liczbę wierszy w tabeli. Jednak, i to jest duże, jeśli jakikolwiek proces wstawia lub usuwa wiersze z tabeli, będzie to w najlepszym razie dobre przybliżenie iw zależności od tego, czy twoja baza danych zbierze statystyki automatycznie może być okropnie nie tak.

Ogólnie rzecz biorąc, zawsze lepiej jest faktycznie policzyć liczbę wierszy w tabeli, a następnie opierając się na tabelach systemowych.

Powiązane problemy