> SELECT FIRST 1000 * FROM DOOR ORDER BY DOOR_ID
a mozesz sprawdzić jaki bedzie czas bez klauzuli ORDER BY ?
--
Pozdrawiam
Morff
----------------------
AQQ 141151
Powered by Opera/M2
Rewelacyjnie niski, lecz wyświetlanie danych bez tej klauzuli jest
bezsensowne.
Owszem mógłbym pobierać dane i sobie sortować programowo, ale wówczas
musiałbym pobrać wszystkie 500000 rekordów a to by trwało i trwało - około
90 sekund.
>
> U¿ytkownik "Morff" <mor...@wp.pl> napisa³ w wiadomo¶ci
> news:op.s1u6yys8q0kutt@nt_januszk.herby...
>> Dnia 16-12-2005 o 07:46:22 Andrzej D±browski <andr...@sims.pl> napisa³:
>>
>>
>>> SELECT FIRST 1000 * FROM DOOR ORDER BY DOOR_ID
>>
>> a mozesz sprawdziæ jaki bedzie czas bez klauzuli ORDER BY ?
>>
>
> Rewelacyjnie niski, lecz wy¶wietlanie danych bez tej klauzuli jest
> bezsensowne.
> Owszem móg³bym pobieraæ dane i sobie sortowaæ programowo, ale wówczas
> musia³bym pobraæ wszystkie 500000 rekordów a to by trwa³o i trwa³o -
> oko³o
> 90 sekund.
moze więc warto pomyśleć o zmianie parametrów SortMemBlockSize oraz
SortMemUpperLimit , lub jezeli ramu jest niezbyt duzo zmienić w
environmentach FIREBIRD_TMP (lub w firebird.conf parametr TempDirectories)
na katalog na szybszym dysku ..
Mam prośbę mógłbyś dać namiary na dokument z którego korzystałeś, lub opisać
coś więcej?
Jak to zrobić, co dokałdnie oznaczają te parametry itp?
To samo zapytanie przetwarza się w około 0,5 sekundy zamiast 450 sekund
jeśli nie ma order by
Andrzej Dąbrowski
>> moze wiêc warto pomy¶leæ o zmianie parametrów SortMemBlockSize oraz
>> SortMemUpperLimit , lub jezeli ramu jest niezbyt duzo zmieniæ w
>> environmentach FIREBIRD_TMP (lub w firebird.conf parametr
>> TempDirectories)
>> na katalog na szybszym dysku ..
>
> Mam pro¶bê móg³by¶ daæ namiary na dokument z którego korzysta³e¶, lub
> opisaæ
> co¶ wiêcej?
> Jak to zrobiæ, co doka³dnie oznaczaj± te parametry itp?
> To samo zapytanie przetwarza siê w oko³o 0,5 sekundy zamiast 450 sekund
> je¶li nie ma order by
> Andrzej D±browski
jezeli bez ORDER BY robi sie szybko to znaczy ze wiekszosć czasu serwer
zuzywa na posortowanie twojego zapytania , nie odkrywam tu ameryki -
wyniki mówią za siebie. Co do parametrów : jezeli angielski nie stanowi
problemu to zajrzyj do firebird.conf - masz tam w komentarzach opisane do
czego wymienione parametry służą a na pl.comp.delphi.bazy-danych jeden
prawie święty Kamil zamieścił przykładową konfigurację swojego serwera z
króciutkim opisem (wątek "Strojenie bazy danych Firebird").
Użytkownik "Andrzej Dąbrowski" <andr...@sims.pl> napisał w wiadomości
news:dntns8$p2q$1...@atlantis.news.tpi.pl...
> Witam!
> Mam taki "prosty" problem, jak przyspieszyć wykonywanie się zapytania -
baza
> danych Firebird.
> Zapytanie składa się z left joinów sporej ilości tabel. Poukładałem wg.
> największych redukcji zapytania w where, oraz wielkości przyłączanych
tabel
> itd itp, pozakładałem indexy, ale jak jest duża ilość rekordów
> wyjścioweych - około 500 000 to działa po prostu wolno. Zrobiłem z całości
> VIEW - o wdzięcznej nazwie door i jak dam:
> SELECT FIRST 1000 * FROM DOOR ORDER BY DOOR_ID
> To zaczynają się schody bo trwa zapytanei koło 6-7 minut.
A sprawdzałeś jak wygląda plan tego zapytania? Wydaje mi się niemożliwe,
żeby to miało trwać aż tak długo (w końcu to tylko 1000 rekordów)jeśli FB
prawidłowo skorzysta z indeksów. Może optymalizator dobiera je w
niewłaściwej kolejności... To znaczy nie znam warunku WHERE, więc nie mogę
mieć pewności, ale jeśli chodzi o samo sortowanie to moim zdaniem konieczny
jest indeks na DOOR_ID oraz wszystkie, które są potrzebne do złączeń. I
powinny zostać użyte w tej właśnie kolejności (pierwszy na DOOR_ID, a potem
następne. Miałem swego czasu do czynienia z bazą, w której dołożenie pewnego
indeksu do tabeli powodowało dramatyczne spowolnienie zapytania, bo
optymalizator korzystał z tego nowego indeksu zamiast z innego, który w tym
konkretnym zapytaniu był de facto lepszy. Dodanie klauzuli PLAN ustawiało go
z powrotem "do pionu". No chyba, że nie da się zbudować takiego planu, żeby
FB w ogóle nie musiał sortować i jednocześnie szybko realizował warunek
WHERE, ale sądzę, że coś powinno się udać z tym zrobić. Warto pamiętać, że
niezoptymalizowany warunek ma złożoność liniową a sortowanie n.p. kwadratową
czy n_log_n. A swoją drogą - ile byłoby rekordów wyjściowych gdyby w Twoim
widoku pominąć WHERE?
PS. Możesz gdzieś wystawić tę bazę? Nie chodzi mi o dane, więc może być sama
struktura, ale z danymi lepiej się testuje.
--
Pozdrawiam :-)
Bartek
> Bez where jakies 400000 rekordów, poza tym długie składanie.
> Róznica jest ponieważ first 1000 jest ograniczeniem typowo hmm ja je nazywam
> sprzetowym - nei ma nic do sqla
>
Mylisz się. W PostgreSQL'u w zależności do istniejącego ograniczenia lub
nie, plan zaptania jest zupełnie inny. Przy pewnym ograniczeniu ilości
rekordów zaczynają być używane indeksy, a gdy baza ma zwrócić dużo
rekordów, wtedy niekoniecznie. Pewnie w FB jest podobnie.
> tylko informacje ze 1000 pierwszych
> rekordów, problem jest z tym ze bez order by wybiera rzeczywiście pierwszy
> tysiąc i wyrzuca, a z musi wybrac wszystkie posortowac i dopiero wtedy
> wyrzuca pierwszy 1000.
> Indexy mam jak mówisz, co więcej nawet mam poindeksowane najczęsciej uzywane
> pola w klauzuli where, np. date. Dzięki temu uzysuję spory skrót czasowy,
> ale od pewnej wielkości niewiele to daje. O kaluzuli PLAN nei słyszałem,
> można sie czegoś więcej dowiedzieć?
A google już wyłączyli?
pozdrawiam
Robert Grabowski
Użytkownik "Andrzej Dąbrowski" <andr...@sims.pl> napisał w wiadomości
news:dnueno$24v$1...@atlantis.news.tpi.pl...
[...]
> Bez where jakies 400000 rekordów,
????
400 000 !? Chyba jednak nieco więcej (pisałeś, że z WHERE jest ich 500 000).
> poza tym długie składanie.
> Różnica jest ponieważ first 1000 jest ograniczeniem typowo hmm ja je
nazywam
> sprzętowym - nie ma nic do sqla tylko informacje ze 1000 pierwszych
> rekordów, problem jest z tym ze bez order by wybiera rzeczywiście pierwszy
> tysiąc i wyrzuca, a z musi wybrać wszystkie posortować i dopiero wtedy
> wyrzuca pierwszy 1000.
Właśnie dlatego wydaje mi się, że dobrze dobrany plan może Twoją sprawę
rozwiązać, bo np. użyje indeksu do sortowania (więc nie poświęci na nie
czasu), a warunek WHERE zrealizuje bez korzystania z indeksu.
> Indexy mam jak mówisz, co więcej nawet mam poindeksowane najczęściej
używane
> pola w klauzuli where, np. date. Dzięki temu uzyskuję spory skrót czasowy,
> ale od pewnej wielkości niewiele to daje. O kaluzuli PLAN nie słyszałem,
> można się czegoś więcej dowiedzieć?
Nie mam do tego rasowej dokumentacji. Opis w HELP'ie do IB dał mi tylko
tyle, że dowiedziałem się, że jest taka klauzula i nic więcej. Uczyłem się
na przykładach: w IBConsole wpisywałem zapytanie i dawałem polecenie
Query/Prepare. Wtedy w zakładce "Plan" pokazuje się coś takiego:
ja:
select first 100 * from param451 order by param_id
on:
Statement: select first 100 * from param451 order by param_id
PLAN (PARAM451 ORDER PARAM451_PK)
lub
ja:
select first 100 * from param451 order by pole_bez_indeksu
on:
Statement: select first 100 * from param451 order by pole_bez_indeksu
PLAN SORT ((PARAM451 NATURAL))
lub
ja:
select first 100 * from param451 where dop = 1 order by param_id
on:
Statement: select first 100 * from param451 where dop = 1 order by param_id
PLAN SORT ((PARAM451 INDEX (PARAM451_DOP)))
(PARAM451_PK jest indeksem na pole param_id, a PARAM451_DOP na pole dop)
Zauważ, że drugi select nie wykorzystuje indeksu (optymalizator napisał
NATURAL), więc jest zdecydowanie wolniejszy. Ostatni wykorzystuje indeks,
ale nie ten, który jest w tym przypadku najlepszy i zamiast zyskać - traci.
Rzecz w tym, że indeks może być użyty zarówno do sortowania jak i do
wyszukiwania czy do złączeń. FB kiedy ma wiele indeksów może wybrać je
gorzej niż zrobi to człowiek, który wie pewne rzeczy o danych znajdujących
się w tabelach. FB może np. błędnie założyć, że lepiej wykorzystać indeks do
złączenia lub warunku niż do sortowania, bo szybciej pozbędzie się dużej
liczby rekordów i w efekcie do sortowania pozostanie mu mniej. Jednak często
warunek WHERE pozostawia relatywnie dużo danych i jego optymalizowanie nie
na wiele się zda, zaś strata spowodowana koniecznością sortowania jest duża.
Tak może być w Twoim przypadku. Jeśli w poleceniu podasz mu np.:
select first 100 * from param451
where dop = 1
PLAN (PARAM451 ORDER PARAM451_PK)
order by param_id
(jest to treść trzeciego zapytania z planem "wklejonym" z pierwszego)
to wykonasz pierwsze zapytanie, ale zmusisz FB do korzystania z wybranego
przez Ciebie indeksu. Naturalnie cała rzecz komplikuje się w przypadku
złożonych zapytań, ale często efekt jest wart włożonej pracy.
Tak czy inaczej polecam w IBConsole zabawę z "Query/Prepare".
--
Pozdrawiam :-)
Bartek
> Andrzej Dąbrowski wrote:
>
>> Bez where jakies 400000 rekordów, poza tym długie składanie.
>> Róznica jest ponieważ first 1000 jest ograniczeniem typowo hmm ja je
>> nazywam sprzetowym - nei ma nic do sqla
> >
> Mylisz się. W PostgreSQL'u w zależności do istniejącego ograniczenia lub
> nie, plan zaptania jest zupełnie inny. Przy pewnym ograniczeniu ilości
> rekordów zaczynają być używane indeksy, a gdy baza ma zwrócić dużo
> rekordów, wtedy niekoniecznie. Pewnie w FB jest podobnie.
Ale tu nie chodzi o taką sytuację .. W przypadku ograniczenia rekordów
przez WHERE jak najbardziej(najpierw ograniczenie rekordów a potem
sortowanie) - ale tu nie ma ograniczenia rekordów - jest ograniczenie
wyniku zrobione po sortowaniu . Żeby wiedzieć które 1000 rekordów jest
pierwsze trzeba je najpierw przesortować ... wybrać wszystkie (pobiera sie
500 000) , przesortować (sortuje sie 500 000), pokazać pierwsze 1000 wg
sortowania .. a nie wybrać pierwszy 1000 (pobiera sie 1000), sortuje sie
po id (sortuje sie 1000) , pokazuje sie posortowany 1000.
Pomijam temat , ze Andrzej zna Delphi i powienien poradzić sobie w swojej
aplikacji z tym drugim przypadkiem (wybranie w warunku WHERE id pomiedzy
1..1000 , a jezeli user chce to następny 1000) ..
>
> Ale tu nie chodzi o taką sytuację .. W przypadku ograniczenia rekordów
> przez WHERE jak najbardziej(najpierw ograniczenie rekordów a potem
> sortowanie) - ale tu nie ma ograniczenia rekordów - jest ograniczenie
> wyniku zrobione po sortowaniu . Żeby wiedzieć które 1000 rekordów jest
> pierwsze trzeba je najpierw przesortować ... wybrać wszystkie (pobiera
> sie 500 000) , przesortować (sortuje sie 500 000), pokazać pierwsze
> 1000 wg sortowania .. a nie wybrać pierwszy 1000 (pobiera sie 1000),
> sortuje sie po id (sortuje sie 1000) , pokazuje sie posortowany 1000.
>
Nie trzeba wybierać wszystkich. Można posłużyć się indeksem.
Podczas pisania odpowiedzi doskonale zdawałem sobie sprawę z tego, że
zapytanie ma ORDER BY. Jeżeli masz założony indeks na kolumnie/kolumnach
, po których sortujesz, to ograniczenia ilości wyników w samym zapytaniu
potrafi włączyć używanie tego indeksu do wybrania tych "kilku"
największych lub najmniejszych rekordów. Oczywiście jeżeli baza uzna, że
używanie indeksu nie ma sensu, bo szybciej jest przeskanować całą tabelę
i ją posortować, to indeksu nie użyje. Tak dokładnie jest w PostgreSQL'u.
Założyłem, być może błędnie, że podobnie jest w FB.
pozdrawiam
Robert Grabowski
Użytkownik "Robert Grabowski" <gra...@env.pl> napisał w wiadomości
news:dnuq8l$mbj$1...@nemesis.news.tpi.pl...
> Morff wrote:
> > Dnia 16-12-2005 o 15:18:32 Robert Grabowski <gra...@env.pl> napisał:
> >
> [...]
> Nie trzeba wybierać wszystkich. Można posłużyć się indeksem.
>
> Podczas pisania odpowiedzi doskonale zdawałem sobie sprawę z tego, że
> zapytanie ma ORDER BY. Jeżeli masz założony indeks na kolumnie/kolumnach
> , po których sortujesz, to ograniczenia ilości wyników w samym zapytaniu
> potrafi włączyć używanie tego indeksu do wybrania tych "kilku"
> największych lub najmniejszych rekordów. Oczywiście jeżeli baza uzna, że
> używanie indeksu nie ma sensu, bo szybciej jest przeskanować całą tabelę
> i ją posortować, to indeksu nie użyje. Tak dokładnie jest w PostgreSQL'u.
Prawdę mówiąc nie umiem sobie wyobrazić sytuacji kiedy używanie indeksu
sortującego jedynie dla małej liczby rekordów miałoby jakikolwiek sens.
Skoro dla "kilku" rekordów szybsze jest pobieranie ich w prawidłowej
kolejności (posortowanych) i dla każdego z nich wykonywanie złączeń i
sprawdzanie warunków, to z całą pewnością dla większej liczby rekordów
korzyść wynikająca z używania indeksu do sortowania będzie jeszcze większa.
Zwróć uwagę, że sprawdzanie warunku i złączenie mają złożoność liniową, a
sortowanie nie. A może z tymi indeksami jest odwrotnie? Dla dużej liczby
rekordów szuka z indeksem, a dla małej bez... Napisz proszę gdzie można coś
więcej o tym znaleźć, bo bardzo jestem ciekaw.
A swoją drogą, to i tak używanie klauzuli PLAN (lub jej odpowiednika)
potrafi zmienić jakieś zapytanie nie do poznania. Optymalizator nie jest w
stanie dobrać poprawnie indeksów w ogólnym przypadku nawet jeśli rzecz
dotyczy tylko jednej tabeli. Bywa, że tylko człowiek dysponuje potrzebną do
tego wiedzą.
--
Pozdrawiam :-)
Bartek
Dziekuję bardzo za wyjaśnienie, niektórzy nie rozumieją delikatnej sprawy z
dokumentacją do Firebirda.
Jest jej mało, googlowanie zabiera mnóstwo czasu, a mało korzyści, a pójść
sobie do księgarni i kupić książkę z przykładami to nierealne marzenie.
Najgorsze jest to że anwet oficjana literatura ma takie błędy że czasem
wpiosuje się przykład - a on nie chce działać. Dokumentacja od IB bywa
rpzydatna, ale składniowo z reguły się różni. Końcowym tego efektem jest to
że zaczyna się ręcznie i klepie najróżneijsze wersje aż któraś zadziała, a
dopiero potem wie siejak używać.
Andrzej Dabrowski
Masz racje ... trochę pojechałem. Ale na swoje usprawiedliwienie powiem,
że PostgreSQL do wersji 8.1 nie potrafił używać w zapytaniu więcej niż
jednego indeksu dla jednej tabeli. Zatem, jeżeli robiliśmy zapytanie, w
którym wyszukiwaliśmy po indeksie i jednocześnie sortowaliśmy po
indeksie, to w zależności od limitu rekordów potrafił skorzystać, albo z
jednego, albo z drugiego, ale nie z obu. Pewnie mnie to zmyliło.
> Zwróć uwagę, że sprawdzanie warunku i złączenie mają złożoność liniową, a
> sortowanie nie. A może z tymi indeksami jest odwrotnie? Dla dużej liczby
> rekordów szuka z indeksem, a dla małej bez... Napisz proszę gdzie można coś
> więcej o tym znaleźć, bo bardzo jestem ciekaw.
> A swoją drogą, to i tak używanie klauzuli PLAN (lub jej odpowiednika)
> potrafi zmienić jakieś zapytanie nie do poznania. Optymalizator nie jest w
> stanie dobrać poprawnie indeksów w ogólnym przypadku nawet jeśli rzecz
> dotyczy tylko jednej tabeli. Bywa, że tylko człowiek dysponuje potrzebną do
> tego wiedzą.
>
Używałem FB w wersji 1.0.2 i znam ten problem. Miałem w aplikacji
zapytanie, które budowało się dynamicznie w zależności od tego, jakie
pola wypełnił użytkownik. Niestety również PLAN był dla tych zapytań
budowany dynamicznie. Koszmar. Po przesiadce na PostgreSQL'a wszystkie
problemy zniknęły. Serwer sam sobie dobiera najbardziej optymalny plan
zapytania i rzadko mu się zdarza nie trafić.
pozdrawiam
Robert Grabowski