2013-08-04 18 views
10

Załóżmy następującą kwerendę:Kiedy zapytanie SELECT zaczyna zwracać wiersze?

SELECT * FROM table; 

będzie DBMS dać mi pierwszy wiersz tak szybko, jak to pobrane, czy będzie to pierwszy pobrać wszystkie wiersze (zapisywać je w jakimś buforze), a następnie dać mi wszystko wiersze naraz?

Jeśli moje pytanie nie było jasne. Załóżmy, że liczba wierszy w table jest taka, że ​​DBMS zajmie dokładnie 60 minut, aby pobrać wszystkie wiersze. Czy system DBMS zwróci wiersze progresywnie przez 60 minut, czy też będę musiał poczekać 60 minut przed otrzymaniem jakichkolwiek danych?

+3

Hmmm ... interesujące. Co sugerowały twoje testy? –

+0

@AndrewMorton Moje testy sugerują, że korzysta z pewnego rodzaju pamięci podręcznej. Sądzę też, że łatwiej byłoby obsługiwać transakcje z użyciem pamięci podręcznej. Ale do tej pory testowałem tylko z 'psql', więc nie wiem, czy zachowanie jest spowodowane' psql' lub z powodu dbms. –

+2

psql ma takie samo zachowanie jak typowa prosta aplikacja. Jest on oparty na libpq, więc libpq zbiera wszystkie dane w pamięci po stronie klienta, a kiedy zapytanie jest kompletne, zwraca kontrolę do klienta. Możesz przedefiniować go za pomocą kursorów, ustawiając FETCH_COUNT na 1000 (zwraca klientowi po pobraniu 1000 wierszy) - \ set FETCH_COUNT 1000 –

Odpowiedz

8

W PostgreSQL serwer rzeczywiście zwróci wiersze do klienta, gdy tylko będą dostępne, jeśli plan wykonania kwerendy na to zezwoli. Tak jest w twoim prostym przykładzie. W innych przypadkach, na przykład, możesz mieć sortowanie na końcu i będziesz musiał czekać, aż to się skończy.

Ale jeśli używasz standardowego interfejsu libpq, biblioteka klienta zbuduje cały wynik w pamięci, zanim zwróci go do programu klienckiego. Aby uzyskać wyniki wiersz po wierszu, należy użyć wartości single-row mode w libpq. Jeśli używasz innych interfejsów lub innych języków, wyniki mogą się różnić.

+0

Czy znasz jakieś rozwiązanie sprzed 9.2? –

+0

Użyj kursora po stronie serwera. –

0

To zależy.

Na przykład bazy danych Oracle optymalizacji przepustowości domyślnie i starają się zwrócić wszystkie wiersze, czy można polecić optymalizator aby powrócić pierwsze n wiersze z `/ * + FIRST_ROWS (N) */optimizer hint.

Jeśli chodzi o PostgresSQL, nie ma wskazówek dotyczących optmizera (patrz: linki o numerach thesetwo). Mogę założyć, że będzie próbował zoptymalizować przepustowość domyślnie.

+4

PostgreSQL nie używa podpowiedzi do tego celu, ale gdy używasz kursora, zapytanie jest zoptymalizowane dla szybkich pierwszych 10% wierszy (domyślna wartość cursor_tuple_fraction). –

3

Nie ma tu twardej reguły. Jednak w praktyce silnik bazy danych powinien preferować zwracanie wierszy, gdy tylko będą dostępne. Zaleta efektywności jest duża i oczywista.

Należy pamiętać, że nie jest to możliwe w przypadku wszystkich zapytań. Bardzo częstym przykładem jest klauzula order by, która nie ma indeksu pomocniczego. Aby sortować, baza danych musi utworzyć po stronie serwera kopię posortowanej tabeli. Oznacza to, że nie można rozpocząć zwracania wierszy, dopóki operacja sortowania nie zostanie zakończona.

1

Większość, jeśli nie wszystkie, serwery oparte na SQL nie pozwalają na przeglądanie żadnych wierszy, dopóki zapytanie nie zakończy wyszukiwania. Niektóre serwery udostępniają dyrektywę FIRST ROWS (wskazówkę) dla serwera, aby szybciej dostarczyć pierwszy zestaw wierszy. Zobacz mój powiązany SO question and answers, aby uzyskać więcej informacji na ten temat.

Powiązane problemy