Zwraca nazwa_tabeli i nazwa_partycji których liczba ma wartość 0

głosy
1

Staram się pisać kwerendy powrotu nazwa_tabeli i nazwa_partycji którego liczba tej partycji mają wartość 0.

Mam poniżej kwerendy, która zwróci SELECT COUNT () z tabelami i jego partycji:

SELECT 'SELECT COUNT(*) FROM ' || TABLE_NAME || ' PARTITION (' || PARTITION_NAME || ');'
FROM user_tab_partitions
ORDER BY table_name;

Są to jedne z SELECT że powrót:

SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201210);
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201104);
SELECT COUNT(*) FROM A5109713 PARTITION (PT5109713_201301);

Ten ostatni to jedyny że dane powrotne:

COUNT(*) |
2430276  |

Co potrzebne jest zapytanie, które zwróci nazwa_tabeli i nazwa_partycji tych, którzy nie ma danych. Coś takiego:

TABLE_NAME | PARTITION_NAME
A5109713   | PT5109713_201210
A5109713   | PT5109713_201104
Utwórz 13/02/2020 o 21:52
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
0

Ta metoda z wykorzystaniem dynamicznego SQL jest ciężkie do zrealizowania, i powoli do wykonywania (ponieważ trzeba ręcznie liczyć wierszy w każdej partycji). Również teraz znaleźć się w potrzebie dodatkowej logiki, która będzie wymagać więcej kodu PL / SQL.

Widok System user_tab_partitionsposiada kolumnę o nazwie num_rows, która jest udokumentowana jak : liczba wierszy w partycji . Wiarygodność informacji w nim zawartych zależy od świeżości statystyk.

Tak więc, jeśli statystyki są na bieżąco, a następnie można uzyskać informacje, które szukasz bezpośrednio z widoku:

select table_name, partition_name
from user_tab_partitions
where num_rows = 0
order by table_name, partition_name
Odpowiedział 13/02/2020 o 22:11
źródło użytkownik

głosy
0

miałbym procedura tak:

DECLARE
    r INTEGER;
    cur sys_refcursor;
BEGIN
    FOR aPart IN (SELECT TABLE_NAME, PARTITION_NAME FROM USER_TAB_PARTITIONS ORDER BY TABLE_NAME, PARTITION_POSITION) LOOP
        OPEN cur FOR 'SELECT ROWNUM FROM '||aPart.TABLE_NAME||' PARTITION ('||aPart.PARTITION_NAME||') WHERE ROWNUM <= 1';
        FETCH cur INTO r;
        IF cur%NOTFOUND THEN
            DBMS_OUTPUT.PUT_LINE(aPart.TABLE_NAME||CHR(9)||aPart.PARTITION_NAME);
        end if;
        close cur;
    END LOOP;
END;

I nie będzie polegać na NUM_ROWSna widok USER_TAB_PARTITIONSponieważ rzetelność informacji w nim zawartych zależy od świeżości statystyk.

Używam SELECT ROWNUM FROM ... WHERE ROWNUM <= 1;zamiast COUNT(*)do rozumu wydajności. Właściwie nie jesteś zainteresowany w ogólnej liczbie rzędach, po prostu chciałbym wiedzieć, czy są one większe niż 0.

W najgorszym przypadku COUNT(*)prowadzi Full-skanowanie tabeli, która jest znacznie wolniejsza niż czyta tylko pierwszy rekord.

Odpowiedział 14/02/2020 o 11:35
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more