2010-07-01 12 views
7

Mam tabeli z miliardów wierszy i chciałbym, aby określić średni czas i odchylenie standardowe czasu przez kilka zapytań w postaci:Statystyki dotyczące czasie kwerendy (PostgreSQL)

select * from mytable where col1 = '36e2ae77-43fa-4efa-aece-cd7b8b669043'; 
select * from mytable where col1 = '4b58c002-bea4-42c9-8f31-06a499cabc51'; 
select * from mytable where col1 = 'b97242ae-9f6c-4f36-ad12-baee9afae194'; 

.... 

Mam tysiąc losowe wartości dla col1 zapisane w innej tabeli.

Czy istnieje sposób na zapisanie, ile czasu zajęło każde z tych zapytań (w milisekundach) w oddzielnej tabeli, aby można było uruchomić na nich statystyki? Coś jak: dla każdego col1 w mojej losowej tabeli, wykonaj zapytanie, zapisz czas, a następnie zapisz go w innej tabeli.

Zupełnie inne podejście byłoby w porządku, o ile mogę pozostać w PostgreSQL (tj. Nie chcę pisać do tego zewnętrznego programu).

Odpowiedz

6

Czy znasz numer EXPLAIN statement?

To polecenie wyświetla plan wykonania, który generator PostgreSQL generuje dla dostarczonej instrukcji. Plan wykonania pokazuje, w jaki sposób tabela (i), do których odwołuje się instrukcja, zostanie zeskanowany - przez zwykłe skanowanie sekwencyjne, skanowanie indeksu itp. - i jeśli odwołano się do wielu tabel, jakie algorytmy łączenia zostaną użyte do zgromadzenia wymaganych wierszy z każdego z nich tabela wejściowa.

Najważniejszą częścią wyświetlacza jest szacunkowy koszt wykonania wyciągu, który jest planistycznym przypuszczeniem, jak długo potrwa wykonanie wyciągu (mierzone w jednostkach pobranych na stronie dysku). W rzeczywistości są wyświetlane dwie liczby: czas rozruchu przed zwróceniem pierwszego wiersza i łączny czas na zwrócenie wszystkich wierszy. Dla większości zapytań liczy się całkowity czas, ale w kontekstach takich jak podzapytanie w EXISTS, planista wybierze najmniejszy czas rozpoczęcia zamiast najmniejszego całkowitego czasu (ponieważ executor zatrzyma się po uzyskaniu jednego rzędu). Ponadto, jeśli ograniczysz liczbę wierszy do zwrócenia z klauzulą ​​LIMIT, planista dokonuje odpowiedniej interpolacji między kosztami punktu końcowego, aby oszacować, który plan jest naprawdę najtańszy.

Opcja ANALYZE powoduje, że instrukcja jest faktycznie wykonywana, a nie tylko planowana. Całkowity czas, jaki upłynął w każdym węźle planu (w milisekundach) i całkowita liczba wierszy, które faktycznie zostały zwrócone, są dodawane do ekranu. Przydaje się to do sprawdzenia, czy prognozy planisty są zbliżone do rzeczywistości.

można dość łatwo napisać skrypt, który robi się EXPLAIN ANALYZE na zapytania dla każdego z losowymi wartościami w tabeli i zapisać dane wyjściowe do pliku/tabela/itp

+0

Czy jest jakiś sposób, aby po prostu wydrukować czas, tak, że nie trzeba analizować pliku? To właśnie zrobię, jeśli będę musiał, ale wydaje mi się, że powinien być prostszy sposób. –

+0

'psql -c" WYBIERZ ANALIZĘ wybierz * z mytable gdzie col1 ... "| grep "Total runtime" ' –

+0

Naprawdę szukam sposobu, aby to zrobić całkowicie w SQL, jeśli to możliwe. Wygląda na to, że powinienem móc zapisać środowisko wykonawcze zwracane w powłoce interaktywnej psql bezpośrednio jako wartość. Twoja odpowiedź jest całkiem poprawna i jest tym, co planowałem zrobić, jeśli nikt nie może mi dać odpowiedzi na czysto SQL. Dziękujemy za poświęcony czas! –

11

trzeba zmienić Plik konfiguracyjny PostgreSQL.

Czy włączyć tę właściwość:

log_min_duration_statement = -1  # -1 is disabled, 0 logs all statements          
             # and their durations, > 0 logs only          
             # statements running at least this number         
             # of milliseconds    

potem, czas realizacji zostanie zarejestrowana i będzie można dowiedzieć się dokładnie, jak źle (albo dobrze) wykonują zapytania.

Można również użyć niektórych narzędzi LOG PARSING, aby zapewnić niesamowite wyjście HTML do dalszej analizy, takiej jak pgfouine.

0

NIE MOŻNA zrobić tego w SQL, ponieważ nawet gdyby można było wywoływać każdą z tych instrukcji w pętli, każde wywołanie do teraz() zwróciłoby ten sam wynik, ponieważ jesteś w pojedynczej transakcji.

Jest to po prostu możliwe, tworząc własną funkcję volatile now(), zwracając inną wartość przy każdym wywołaniu.

2

Bezpośrednio, nie, nie ma. Ale możesz zrobić oszacowanie pośrednie i dość bliskie, sprawdzając czas tuż przed zapytaniem, które interesuje Cię czas.

$sql = "Your Query"; 
$bm = "SELECT extract(epoch FROM clock_timestamp())"; 
$query = "{$bm}; {$sql}; {$bm};"; 

Funkcja clock_timestamp() podaje serwerowi aktualny czas rozpoczęcia instrukcji. Ponieważ SELECT nie zawiera tabel, możemy oczekiwać, że będzie to niemal natychmiastowe. Chyba każdy sterownik Pg oferuje obsługę wielu zapytań; ważne jest, aby te 3 pytania (rzeczywisty i 2 dodatki) pasowały do ​​siebie, w przeciwnym razie mierzyłbyś również czas transportu danych ...

Dla PHP mam funkcję, aby sobie z tym poradzić. Podsumowując, wygląda tak:

<?php 

function pgquery($sql, $conn) 
{ 
    // Prepend and append benchmarking queries 
    $bm = "SELECT extract(epoch FROM clock_timestamp())"; 
    $query = "{$bm}; {$sql}; {$bm};"; 

    // Execute the query, and time it (data transport included) 
    $ini = microtime(true); 

    pg_send_query($conn, $query); 

    while ($resource = pg_get_result($conn)) 
    { 
     $resources[] = $resource; 
    } 

    $end = microtime(true); 

    // "Extract" the benchmarking results 
    $q_ini = pg_fetch_row(array_shift($resources)); 
    $q_end = pg_fetch_row(array_pop($resources)); 

    // Compute times 
    $time = round($end - $ini, 4);    # Total time (inc. transport) 
    $q_time = round($q_end[0] - $q_ini[0], 4); # Query time (Pg server only) 

    return $resources; 
} 

?> 

Właśnie opuściłem podstawy. $ conn przechowuje łącze do połączenia Pg, a $ resources to tablica zwróconych zasobów pg (w przypadku gdy wysłałeś wiele zapytań do twojego $ sql).

$ czas pozostawia całkowity czas od momentu pozostawienia zapytania do serwera Pg, dopóki nie nadejdzie wynik. $ q-time zawiera tylko rzeczywisty czas zapytania, który chciałeś (lub bardzo dobre przybliżenie).

Dodaj obsługę błędów i inne przetwarzanie według własnych upodobań, mam wiele, ale nie ma to znaczenia dla twojego pytania.

Powiązane problemy