🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.bazy-danych
50 messages
50 total messages Started by Marek Tue, 24 Feb 2015 15:23
PostgreSQL - jak zbudować optymalne zapytanie?
#194303
Author: Marek
Date: Tue, 24 Feb 2015 15:23
23 lines
1303 bytes
Witam,

Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze 
sobą następująco:

tabela1.pole=tabela2.pole

Kłopot w tym, że tabela2 posiada wiele nulli. Pomyślałem więc, że 
zbuduję indeks częściowy:

CREATE INDEX costam ON tabela2 WHERE pole NOTNULL

I teraz moje pytanie brzmi: jak wiązać obie tabele aby wykorzystać ten 
indeks? Czy:

1. tabela1.pole=tabela2.pole
2. tabela1.pole=tabela2.pole AND tabela2.pole NOTNULL

Ma to w ogóle znaczenie?

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194301
Author: Adam
Date: Tue, 24 Feb 2015 22:36
31 lines
1582 bytes
W dniu 2015-02-24 o 16:23, Marek pisze:
> Witam,
>
> Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze
> sobą następująco:
>
> tabela1.pole=tabela2.pole
>
> Kłopot w tym, że tabela2 posiada wiele nulli. Pomyślałem więc, że
> zbuduję indeks częściowy:
>
> CREATE INDEX costam ON tabela2 WHERE pole NOTNULL
>
> I teraz moje pytanie brzmi: jak wiązać obie tabele aby wykorzystać ten
> indeks? Czy:
>
> 1. tabela1.pole=tabela2.pole
> 2. tabela1.pole=tabela2.pole AND tabela2.pole NOTNULL
>
> Ma to w ogóle znaczenie?
>

Ty chcesz zbudować jakąś relację? Jakiego rodzaju?

Może napisz, co chcesz uzyskać i podaj przykład.


-- 
Pozdrawiam.

Adam
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194299
Author: Tomek Kańka
Date: Tue, 24 Feb 2015 22:46
25 lines
1576 bytes
Marek <precz@spamowi.com> napisał(a)
> Witam,
>
> Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze 
> sobą następująco:
>
> tabela1.pole=tabela2.pole
>
> Kłopot w tym, że tabela2 posiada wiele nulli. 
>[...]

Mam 20+ lat doświadzenia w pisaniu zawodowo programów. Duża ich cześć
korzysta z baz danych. I wiecie co...

Nigdy nie przyszło mi do głowy zastanawianie się nad tym ile tabela
posiada null-i!

Czy Twój program działa zbyt wolno, zużywa za dużo zasobów? Jeśli tak,
to znajdź przyczynę i dopiero poprawiaj. Może trzeba będzie założyc
indeks, może przeprojektować strukturę, może zdenormalizować.

IMHO to czym sie zajmujesz, to "premature optimization".

-- 
Tomek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194298
Author: Czarek Grądys
Date: Wed, 25 Feb 2015 07:10
26 lines
1663 bytes
W dniu 24.02.2015 o 16:23, Marek pisze:
> Witam,
>
> Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze
> sobą następująco:
>
> tabela1.pole=tabela2.pole
>
> Kłopot w tym, że tabela2 posiada wiele nulli. Pomyślałem więc, że
> zbuduję indeks częściowy:
>
> CREATE INDEX costam ON tabela2 WHERE pole NOTNULL
>
> I teraz moje pytanie brzmi: jak wiązać obie tabele aby wykorzystać ten
> indeks? Czy:
>
> 1. tabela1.pole=tabela2.pole
> 2. tabela1.pole=tabela2.pole AND tabela2.pole NOTNULL
>
> Ma to w ogóle znaczenie?
>

Nie chodzi przypadkiem o LEFT, RIGHT albo FULL JOIN?
-- 
Cezary Grądys
czarekgr@wa.onet.pl
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194295
Author: nkab
Date: Wed, 25 Feb 2015 11:18
39 lines
2586 bytes
W dniu wtorek, 24 lutego 2015 16:23:35 UTC+1 użytkownik Marek napisał:
> Witam,
> 
> Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze 
> sobą następująco:
> 
> tabela1.pole=tabela2.pole
> 
> Kłopot w tym, że tabela2 posiada wiele nulli. Pomyślałem więc, że 
> zbuduję indeks częściowy:
> 
> CREATE INDEX costam ON tabela2 WHERE pole NOTNULL
> 
> I teraz moje pytanie brzmi: jak wiązać obie tabele aby wykorzystać ten 
> indeks? Czy:
> 
> 1. tabela1.pole=tabela2.pole
> 2. tabela1.pole=tabela2.pole AND tabela2.pole NOTNULL
> 
> Ma to w ogóle znaczenie?
> 

Rozumiem, że chcesz tak jakby krótszy plik indeksowy?
Według mnie to błąd, bo przy wykorzystywaniu takiego
indeksu w zapytaniach musiałbyś zawsze dawać warunek na te NULLe.

W ogóle indeksy zawsze zakładaj na wszystkie rekordy a jakieś
pomijanie robisz potem w WHERE.

Z indeksami jest tak, że nawet jak zrobisz jakiś DELETE rekordu
to on nie jest usuwany z dysku i indeks jest dla niego cały
czas aktualny a przy reindex odnawiany.
Dopiero przeniesienie danych to nowej tabeli może pominąć rekordy
usunięte (zmiejszyć tabelę, zajętość dysku) ale wymaga to również
utworzenia od nowa indeksów.

I rzeczywiście dlaczego aż tyle tych nuli.

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194297
Author: Marek
Date: Wed, 25 Feb 2015 13:53
23 lines
1319 bytes
W dniu 2015-02-24 o 23:36, Adam pisze:

>
> Ty chcesz zbudować jakąś relację? Jakiego rodzaju?
>
> Może napisz, co chcesz uzyskać i podaj przykład.
>

Hej.

Relacja będzie między dwoma polami typu int4.

CREATE TABLE tabela1 (pole SERIAL PRIMARY KEY...

a tabelą

CREATE TABLE tabela1 (pole int4 ...

Pola nie będą ze sobą powiązane wprost constraintem.

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194296
Author: Marek
Date: Wed, 25 Feb 2015 13:58
22 lines
1516 bytes
W dniu 2015-02-24 o 23:46, Tomek Kańka pisze:


> Nigdy nie przyszło mi do głowy zastanawianie się nad tym ile tabela
> posiada null-i!

http://stackoverflow.com/questions/3467982/indexing-null-values-in-postgresql

Tu masz przypadek kolegi, który też się nad tym nie zastanawiał i słono 
za to zapłacił wydajnością.

> Czy Twój program działa zbyt wolno, zużywa za dużo zasobów?

Tego jeszcze nie wiem i wolę dowiedzieć się zanim aplikacja ruszy. :-)

> IMHO to czym sie zajmujesz, to "premature optimization".

Zajmuję się dmuchaniem na zimne :-D

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194300
Author: Marek
Date: Wed, 25 Feb 2015 13:59
9 lines
1113 bytes
W dniu 2015-02-25 o 08:10, Czarek Grądys pisze:
>
> Nie chodzi przypadkiem o LEFT, RIGHT albo FULL JOIN?

Póki co mam swobodę decydowania. Zapewne tak będzie.

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194283
Author: Marek
Date: Wed, 25 Feb 2015 14:22
27 lines
1806 bytes
W dniu 2015-02-25 o 12:18, nkab@toya.net.pl pisze:

>
> Rozumiem, że chcesz tak jakby krótszy plik indeksowy?

Hmm. Niekoniecznie. Chcę uniknąć niespodzianek jak tu:

http://stackoverflow.com/questions/3467982/indexing-null-values-in-postgresql 


> W ogóle indeksy zawsze zakładaj na wszystkie rekordy a jakieś
> pomijanie robisz potem w WHERE.

Czyli lepiej będzie założyć indeks pełny i filtrować nulle w WHERE? A 
czy to jest celowe? Jeśli np. zJOINuję dwie tabele, gdzie jedna ma pełno 
nulli, to i tak otrzymam rekordy nie zawierające nulli na joinowanych 
polach.

> I rzeczywiście dlaczego aż tyle tych nuli.

Bo chodzi o to iż druga tabela przechowuje dane dla wielu różnych innych 
relacji. Implementacja modelu EAV jaką uzgodniliśmy w innym wątku. Teraz 
ją wdrażam właśnie.

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194288
Author: szaman
Date: Wed, 25 Feb 2015 15:55
9 lines
2326 bytes
Właściwie to nie mam pojęcia o jaką bazę danych chodzi bo w różnych może to różnie działać :-)

Jeżeli jest możliwość zrobienia takiego indeksu to jak najbardziej warto go zrobić.
W Oracle to zdaje si że każdy indeks nie zawiera rekordów dla których klucz indeksu jest NULL. W MSSQL jest już inaczej ale od jakiegoś czasu są takie filtrowane indeksy.

Pierwszą i najważniejszą zasadą optymalizowania zapytań SQL (i nie tylko :-) ) jest ograniczenie liczby danych do przeszukania czy zwrócenia, itp. - dotyczy to nie tylko liczby rekordów ale i ich rozmiaru.
Takie indeksy jak najbardziej w tą zasadę się wpisują. 
Co do postaci klauzuli WHERE to nie powinno to mieć znaczenia - ale :-) to nie zawsze prawda bo nawet jak to się dzieje w przypadku MSSQL optymalizator inaczej działa w różnych edycjach (oczywiście w enterprise działa najlepiej :-) )
Musisz popróbować i sprawdzić plan wykonania zapytania a w razie czego przymusić optymalizator jakimś hintem czy dyrektywą jak będzie zbyt oporny.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194284
Author: szaman
Date: Wed, 25 Feb 2015 15:58
2 lines
1724 bytes
Przepraszam za gapiostwo - w pytaniu masz podany rodzaj bazy :-)
Nie zmienia to jednak mojej odpowiedzi w jakiś istotny sposób ;-)
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194289
Author: Lesiok
Date: Wed, 25 Feb 2015 17:59
45 lines
2751 bytes
W dniu 2015-02-25 o 15:22, Marek pisze:
> W dniu 2015-02-25 o 12:18, nkab@toya.net.pl pisze:
>
>>
>> Rozumiem, że chcesz tak jakby krótszy plik indeksowy?
>
> Hmm. Niekoniecznie. Chcę uniknąć niespodzianek jak tu:
>
> http://stackoverflow.com/questions/3467982/indexing-null-values-in-postgresql
>
>
>> W ogóle indeksy zawsze zakładaj na wszystkie rekordy a jakieś
>> pomijanie robisz potem w WHERE.
>
> Czyli lepiej będzie założyć indeks pełny i filtrować nulle w WHERE? A
> czy to jest celowe? Jeśli np. zJOINuję dwie tabele, gdzie jedna ma pełno
> nulli, to i tak otrzymam rekordy nie zawierające nulli na joinowanych
> polach.
>
>> I rzeczywiście dlaczego aż tyle tych nuli.
>
> Bo chodzi o to iż druga tabela przechowuje dane dla wielu różnych innych
> relacji. Implementacja modelu EAV jaką uzgodniliśmy w innym wątku. Teraz
> ją wdrażam właśnie.
>

W powołanym przez Ciebie linku jest mowa o wersji 8.3/8.4 - obydwie już 
martwe. W serii 9 było zrobionych baaardzo dużo zmian pod kątem wydajności.

Z ciekawości zrobiłem kilka prostych testów z tabelami po 100 mln 
rekordów, po trzy kolumny, wielkość bazy 11 GB. Tabela dołączana z 
wypełnieniem kolumny używanej w warunku łączenia w 50%. PostgreSQL 9.3.6 
na CentOS 6 64-bit, 4 GB RAM.

Definicja indeksu (obecność lub brak klauzuli WHERE NOT pole IS NULL) 
dla tabeli dołączanej nie miała żadnego wpływu na plan zapytania oraz 
czas jego wykonania. Oczywiście wszystko przy założeniach określonych 
przez Ciebie na początku dyskusji.

Wydaje mi się, że problem jest trochę wydumany albo źle przedstawiony.

-- 
Pozdrawiam,

Leszek KUBRAK
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194292
Author: Marek
Date: Fri, 27 Feb 2015 08:34
17 lines
1713 bytes
W dniu 2015-02-25 o 18:59, Lesiok pisze:


> Wydaje mi się, że problem jest trochę wydumany albo źle przedstawiony.

Problem nie jest wydumany lecz rzeczywisty. Wydaje mi się też, że dość 
jasno opisałem o co chodzi i czego chciałbym uniknąć. Owszem, powołałem 
się w celu precyzyjnego zobrazowania na dyskusję dotyczącą wcześniejszej 
wersji bazy ale nie posiadam specjalistycznej wiedzy aby móc samemu 
oszacować czy nowa wersja nie będzie stwarzać podobnych problemów z 
wydajnością. Dlatego zadałem pytanie o to jak należy współcześnie 
postępować proponując do dalszej dyskusji potencjalne rozwiązania gdyby 
problem istniał.

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194286
Author: Lesiok
Date: Fri, 27 Feb 2015 09:55
23 lines
2043 bytes
W dniu 2015-02-27 o 09:34, Marek pisze:
> W dniu 2015-02-25 o 18:59, Lesiok pisze:
>
>
>> Wydaje mi się, że problem jest trochę wydumany albo źle przedstawiony.
>
> Problem nie jest wydumany lecz rzeczywisty. Wydaje mi się też, że dość
> jasno opisałem o co chodzi i czego chciałbym uniknąć. Owszem, powołałem
> się w celu precyzyjnego zobrazowania na dyskusję dotyczącą wcześniejszej
> wersji bazy ale nie posiadam specjalistycznej wiedzy aby móc samemu
> oszacować czy nowa wersja nie będzie stwarzać podobnych problemów z
> wydajnością. Dlatego zadałem pytanie o to jak należy współcześnie
> postępować proponując do dalszej dyskusji potencjalne rozwiązania gdyby
> problem istniał.
>
Swoje wnioski z testu opisałem. Być może test był zbyt prymitywny w 
stosunku do twojego problemu. A tak w ogóle to podpisuję się pod co 
wyżej napisał Tomek Kańka.

-- 
Pozdrawiam,

Leszek KUBRAK
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194304
Author: hubert depesz lubaczewski
Date: Fri, 27 Feb 2015 11:22
31 lines
2275 bytes
On 2015-02-24, Marek <precz@spamowi.com> wrote:
> Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze 
> sobą następująco:
> tabela1.pole=tabela2.pole
> Kłopot w tym, że tabela2 posiada wiele nulli. Pomyślałem więc, że 
> zbuduję indeks częściowy:
> CREATE INDEX costam ON tabela2 WHERE pole NOTNULL
> I teraz moje pytanie brzmi: jak wiązać obie tabele aby wykorzystać ten 
> indeks? Czy:
> 1. tabela1.pole=tabela2.pole
> 2. tabela1.pole=tabela2.pole AND tabela2.pole NOTNULL
> Ma to w ogóle znaczenie?

Po pierwsze - podałeś za mało danych. Sam fakt jak łączysz tabele jest
niemalże nieistotny. Podany przez Ciebie link, sam w sobie może
i ciekawy, ale nie ma większego znaczenia - ważne jest całe zapytanie
które będziesz miał (jakieś klauzule where? group by?).

Po drugie - jakiej mniej więcej skali danych się spodziewasz? Liczba
rekordów i odsetek rekordów w tabela2 z pole is null.

Po trzecie - jeśli indeks ma "not null" to zapytanie też powinno mieć
"not null" - nawet jeśli czasem optymalizator się dopatrzy, że "not
null" nie ma w danym przypadku znaczenia, to lepiej na to nie liczyć
i zapisać warunek poprawnie (kompletnie).

depesz

-- 
The best thing about modern society is how easy it is to avoid contact with it.
                                                             http://depesz.com/
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194291
Author: Marek
Date: Sat, 28 Feb 2015 21:39
14 lines
1428 bytes
W dniu 2015-02-27 o 10:55, Lesiok pisze:

>>
> Swoje wnioski z testu opisałem. Być może test był zbyt prymitywny w
> stosunku do twojego problemu. A tak w ogóle to podpisuję się pod co
> wyżej napisał Tomek Kańka.

Ok, czyli nie mam się o co martwić. Założyć mam zwykły indeks i z głowy?



-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194305
Author: Marek
Date: Sat, 28 Feb 2015 21:47
37 lines
2464 bytes
W dniu 2015-02-27 o 12:22, hubert depesz lubaczewski pisze:

> Po pierwsze - podałeś za mało danych. Sam fakt jak łączysz tabele jest
> niemalże nieistotny. Podany przez Ciebie link, sam w sobie może
> i ciekawy, ale nie ma większego znaczenia - ważne jest całe zapytanie
> które będziesz miał (jakieś klauzule where? group by?).

Nie potrafię przytoczyć bardziej precyzyjnych danych gdyż nie wiem do 
końca jakie informacje będę pobierał w przyszłości z bazy. Jedynym 
pewnikiem jest to, że będę używał złączeń i dlatego do nich się 
ograniczam w wątku.

Czy sugerujesz iż dla złączeń tabel budowanie indeksu jest niepotrzebne?

> Po drugie - jakiej mniej więcej skali danych się spodziewasz? Liczba
> rekordów i odsetek rekordów w tabela2 z pole is null.

Sądzę, że liczba rekordów będzie na poziomie pojedynczych tysięcy. 
Analizuję obecne wykorzystanie CMS w wielu realizacjach i generalnie 
takie mam statystyki. Oczywiście może zdarzyć się rodzynek, gdzie 
rekordów będzie znacznie więcej. Trudno przewidzieć.

Ilość nulli w drugiej tabeli będzie zwykle przytłaczająca. Powiedzmy 90%.

> Po trzecie - jeśli indeks ma "not null" to zapytanie też powinno mieć
> "not null" - nawet jeśli czasem optymalizator się dopatrzy, że "not
> null" nie ma w danym przypadku znaczenia, to lepiej na to nie liczyć
> i zapisać warunek poprawnie (kompletnie).

Czy jest istotna kolejność? Mam na myśli:

a) where a=b and b notnull
b) where b notnull and a=b

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194306
Author: artiun
Date: Sat, 28 Feb 2015 22:24
43 lines
3519 bytes
W dniu 2015-02-28 o 22:47, Marek pisze:
> W dniu 2015-02-27 o 12:22, hubert depesz lubaczewski pisze:
>
>> Po pierwsze - podałeś za mało danych. Sam fakt jak łączysz tabele jest
>> niemalże nieistotny. Podany przez Ciebie link, sam w sobie może
>> i ciekawy, ale nie ma większego znaczenia - ważne jest całe zapytanie
>> które będziesz miał (jakieś klauzule where? group by?).
>
> Nie potrafię przytoczyć bardziej precyzyjnych danych gdyż nie wiem do końca
> jakie informacje będę pobierał w przyszłości z bazy. Jedynym pewnikiem jest
> to, że będę używał złączeń i dlatego do nich się ograniczam w wątku.
>
> Czy sugerujesz iż dla złączeń tabel budowanie indeksu jest niepotrzebne?
>
>> Po drugie - jakiej mniej więcej skali danych się spodziewasz? Liczba
>> rekordów i odsetek rekordów w tabela2 z pole is null.
>
> Sądzę, że liczba rekordów będzie na poziomie pojedynczych tysięcy. Analizuję
> obecne wykorzystanie CMS w wielu realizacjach i generalnie takie mam
> statystyki. Oczywiście może zdarzyć się rodzynek, gdzie rekordów będzie
> znacznie więcej. Trudno przewidzieć.
>
> Ilość nulli w drugiej tabeli będzie zwykle przytłaczająca. Powiedzmy 90%.
>
>> Po trzecie - jeśli indeks ma "not null" to zapytanie też powinno mieć
>> "not null" - nawet jeśli czasem optymalizator się dopatrzy, że "not
>> null" nie ma w danym przypadku znaczenia, to lepiej na to nie liczyć
>> i zapisać warunek poprawnie (kompletnie).
>
> Czy jest istotna kolejność? Mam na myśli:
>
> a) where a=b and b notnull
> b) where b notnull and a=b
>
Nie chcesz napisać co robisz, mi to wygląda na jakiś test, quiz. Przy paru 
tysiącach... chmm. Nir mówię o braku indeksu, ale do takiego celu to 
przewaga formy nad treścią.
Jak byś tego nie analizował, czy krzyżowo, czy wprost z podsumami.

-- 
Artur
0 weeks 0 days 0 hours 32 minutes 35 seconds and 959 milliseconds.
"pl.comp.bazy-danych"
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194290
Author: Lesiok
Date: Sun, 01 Mar 2015 07:05
18 lines
1623 bytes
W dniu 2015-02-28 o 22:39, Marek pisze:
> W dniu 2015-02-27 o 10:55, Lesiok pisze:
>
>>>
>> Swoje wnioski z testu opisałem. Być może test był zbyt prymitywny w
>> stosunku do twojego problemu. A tak w ogóle to podpisuję się pod co
>> wyżej napisał Tomek Kańka.
>
> Ok, czyli nie mam się o co martwić. Założyć mam zwykły indeks i z głowy?
>
>
>
Dokładnie tak.

-- 
Pozdrawiam,

Leszek KUBRAK
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194308
Author: hubert depesz lubaczewski
Date: Sun, 01 Mar 2015 09:09
9 lines
1355 bytes
On 2015-02-28, Marek <precz@spamowi.com> wrote:
> Sądzę, że liczba rekordów będzie na poziomie pojedynczych tysięcy. 
> Analizuję obecne wykorzystanie CMS w wielu realizacjach i generalnie 
> takie mam statystyki. Oczywiście może zdarzyć się rodzynek, gdzie 
> rekordów będzie znacznie więcej. Trudno przewidzieć.

Sorry, ale to zastanawianie się nad optymalizacją tego nie ma sensu.

depesz
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194302
Author: Marek
Date: Sun, 01 Mar 2015 09:35
9 lines
1276 bytes
W dniu 2015-03-01 o 08:05, Lesiok pisze:
>>
> Dokładnie tak.

Dziękuję za poradę :-)

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194307
Author: Marek
Date: Sun, 01 Mar 2015 09:39
15 lines
1469 bytes
W dniu 2015-02-28 o 23:24, artiun pisze:

> Nie chcesz napisać co robisz, mi to wygląda na jakiś test, quiz.

To żaden quiz. Wydaje mi się, że wyczerpująco napisałem co jest moim 
zamiarem: łączenie tabel, przeznaczenie CMS. Co jeszcze mam powiedzieć? 
Nie mam bladego pojęcia czy w danej realizacji to łączenie będzie z 
grupowaniem np a w innej już nie. Zależy od implementacji. Jednakże 
łączenie będzie zawsze i to jest pewnik.



-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194309
Author: Marek
Date: Sun, 01 Mar 2015 09:42
12 lines
1402 bytes
W dniu 2015-03-01 o 10:09, hubert depesz lubaczewski pisze:

> Sorry, ale to zastanawianie się nad optymalizacją tego nie ma sensu.

No dobrze. Zatem zaczekam na wystąpienie konkretnej implementacji. Jeśli 
pojawi się jakiś problem wydajnościowy, z którym sobie nie poradzę - 
wtedy powrócę na forum. Obawiam się tylko, że usłyszę iż trzeba było 
napisać wcześniej - zanim przystąpiłem do realizacji :-D

-- 
Pozdrawiam,
Marek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194310
Author: nkab
Date: Wed, 04 Mar 2015 08:46
20 lines
1991 bytes
W dniu sobota, 28 lutego 2015 22:48:11 UTC+1 użytkownik Marek napisał:
> W dniu 2015-02-27 o 12:22, hubert depesz lubaczewski pisze:
> 
> Czy jest istotna kolejność? Mam na myśli:
> 
> a) where a=b and b notnull
> b) where b notnull and a=b
> 

Mnie jak zależy na czasie wykonania to robię sobie testy.

W manualach są czasami dostępne tabelki z kosztami wykonania
warunków ale mnie się nie chce szukać i robię selecta z około
dziesięcioma takimi b NOTNULL and b NOTNULL...
i sprawdzam czas, następnie też dziesięć takich a=b and a=b...
i sprawdzam czas. Dalej to już sam wiesz co się opłaca.
Możesz też dać dziesięć b notnull and a=b a potem odwrócić
a=b and b notnull i już wiesz co jest lepsze.

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194311
Author: M.M.
Date: Sat, 07 Mar 2015 13:14
23 lines
2258 bytes
On Wednesday, March 4, 2015 at 9:46:31 AM UTC+1, nk...@toya.net.pl wrote:
> W dniu sobota, 28 lutego 2015 22:48:11 UTC+1 użytkownik Marek napisał:
> > W dniu 2015-02-27 o 12:22, hubert depesz lubaczewski pisze:
> > 
> > Czy jest istotna kolejność? Mam na myśli:
> > 
> > a) where a=b and b notnull
> > b) where b notnull and a=b
> > 
> 
> Mnie jak zależy na czasie wykonania to robię sobie testy.
> 
> W manualach są czasami dostępne tabelki z kosztami wykonania
> warunków ale mnie się nie chce szukać i robię selecta z około
> dziesięcioma takimi b NOTNULL and b NOTNULL...
> i sprawdzam czas, następnie też dziesięć takich a=b and a=b...
> i sprawdzam czas. Dalej to już sam wiesz co się opłaca.
> Możesz też dać dziesięć b notnull and a=b a potem odwrócić
> a=b and b notnull i już wiesz co jest lepsze.

Dlaczego robisz z około dziesięcioma takimi?

Pozdrawiam
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194293
Author: M.M.
Date: Sat, 07 Mar 2015 18:46
46 lines
3266 bytes
On Tuesday, February 24, 2015 at 11:46:10 PM UTC+1, Tomek Kańka wrote:
> Marek <precz@spamowi.com> napisał(a)
> > Witam,
> >
> > Mam następującą sytuację. Istnieją dwie tabele, które będą wiązane ze 
> > sobą następująco:
> >
> > tabela1.pole=tabela2.pole
> >
> > Kłopot w tym, że tabela2 posiada wiele nulli. 
> >[...]
> 
> Mam 20+ lat doświadzenia w pisaniu zawodowo programów. Duża ich cześć
> korzysta z baz danych. I wiecie co...
> 
> Nigdy nie przyszło mi do głowy zastanawianie się nad tym ile tabela
> posiada null-i!
Myślę że to dobrze iż się nad tym nie zastanawiałeś :)
Ostatnio robię bardzo prostą analizę. Mam trzy rozwiązania tejże
analizy. Albo analizowany sposób przechowywania danych i generowania 
raportów daje radę, albo nie daję rady, albo jest pewne ryzyko
że nie da rady - czasami zbyt trudno to ocenić. Jeśli daje rade,
to się decyduję na dane rozwiązanie. Jeśli nie, to szukam innego.
Jeśli jest ryzyko, to albo je ponoszę, albo omijam. Nigdy nie
zastanawiałem się, czy jak gdzieś dam indeks z nulem, albo varchar
zamiast chara, to uniknę problemów.

Natomiast gdy już jest jakieś rozwiązanie i przejście na inne
byłoby pracochłonne, to wtedy owszem, można kombinować. Ale
kombinuje się raczej w kierunku ulepszania sprzętu i konfiguracji
bazy. Taka zabawa w dopieszczanie indeksów raczej dużo nie
pomoże, a w dodatku nie ma na to reguły, w każdym przypadku
może być inaczej. Trzeba próbować i robić pomiary. Przy czym
jest to upierdliwe zadanie, bo jak niektóre tabele się
rozrosną, to rozwiązanie które przed rozrostem działało gorzej, 
po rozroście może działać lepiej.


> Czy Twój program działa zbyt wolno, zużywa za dużo zasobów? Jeśli tak,
> to znajdź przyczynę i dopiero poprawiaj. Może trzeba będzie założyc
> indeks, może przeprojektować strukturę, może zdenormalizować.
> 
> IMHO to czym sie zajmujesz, to "premature optimization".
> 
> -- 
> Tomek
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194312
Author: nkab
Date: Mon, 09 Mar 2015 07:55
12 lines
1833 bytes
W dniu sobota, 7 marca 2015 14:14:17 UTC+1 użytkownik M.M. napisał:
> 
> Dlaczego robisz z około dziesięcioma takimi?
> 

Chodziło mi o zachęcenie do eksperymentowania przy testowaniu.
Po prostu testowanie opiera się na dawaniu idiotycznych składni.
Zrobisz to raz i już wiesz, że tu parser tak działa.
Następnie będziesz kombinował z danymi, które również wpływają
na szybkość, jeśli zależy ci na szybkości.

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194313
Author: M.M.
Date: Mon, 09 Mar 2015 11:23
21 lines
2192 bytes
On Monday, March 9, 2015 at 8:55:31 AM UTC+1, nk...@toya.net.pl wrote:
> W dniu sobota, 7 marca 2015 14:14:17 UTC+1 użytkownik M.M. napisał:
> > 
> > Dlaczego robisz z około dziesięcioma takimi?
> > 
> 
> Chodziło mi o zachęcenie do eksperymentowania przy testowaniu.
> Po prostu testowanie opiera się na dawaniu idiotycznych składni.
> Zrobisz to raz i już wiesz, że tu parser tak działa.
> Następnie będziesz kombinował z danymi, które również wpływają
> na szybkość, jeśli zależy ci na szybkości.
> 

Sorki, ale nadal nie kumam.
Testujesz najpierw:
where x < 5;
A potem:
where x < 5 AND x < 6 OR x < 5;

Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
odwrót, że t1>t2.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194314
Author: nkab
Date: Thu, 12 Mar 2015 07:48
25 lines
2274 bytes
W dniu poniedziałek, 9 marca 2015 12:23:28 UTC+1 użytkownik M.M. napisał:
> 
> Sorki, ale nadal nie kumam.
> Testujesz najpierw:
> where x < 5;
> A potem:
> where x < 5 AND x < 6 OR x < 5;
> 
> Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
> odwrót, że t1>t2.
 
Po prostu sprawdzasz czy system poprzestaje na sprawdzeniu
pierwszego członu warunku i dalej już nie sprawdza np.:

if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek


to co to oznacza? Każdy silnik może działać inaczej.

Do testowania najlepiej używać najwolniejszego komputera
bo wtedy te czasy są bardzo widoczne, no i testowane pola
nie powinny mieć indeksów (sprawdzasz tu tylko warunek).

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194315
Author: nkab
Date: Thu, 12 Mar 2015 07:52
3 lines
1596 bytes
...nie "if" ale "where", sorry.

Andrzej. 
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194316
Author: M.M.
Date: Thu, 12 Mar 2015 12:22
52 lines
3745 bytes
On Thursday, March 12, 2015 at 8:48:10 AM UTC+1, nk...@toya.net.pl wrote:
> W dniu poniedziałek, 9 marca 2015 12:23:28 UTC+1 użytkownik M.M. napisał:
> > 
> > Sorki, ale nadal nie kumam.
> > Testujesz najpierw:
> > where x < 5;
> > A potem:
> > where x < 5 AND x < 6 OR x < 5;
> > 
> > Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
> > odwrót, że t1>t2.
>  
> Po prostu sprawdzasz czy system poprzestaje na sprawdzeniu
> pierwszego członu warunku i dalej już nie sprawdza np.:
> 
> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> 
> 
> to co to oznacza? 
Problem w tym, że to może oznaczać bardzo dużo. Zobacz jak
dużo dzieje się w trakcie takiego głupiego zapytania. Najpierw
połączenie z bazą po TCP-IP. Zobacz jak dużo dzieje się na
tym poziomie: uprawnienia, firewalle, szyfrowanie, kompresja,
korekcja błędów. Potem zapytanie dostaje się do bazy, i znowu:
parsowanie, uprawnienia, silnik bazy danych musi sprawdzić czy 
chociaż są w bazie tabele o podanych nazwach. Potem pracuje
kompilator i optymalizator zapytania. Optymalizator może
czasami gromadzić statystyczne dane. Potem bufor systemu
plików i bufor silnika bazy danych. Sorki, ale ja nadal nie
umiem wyciągnąć żadnych wniosków z tego co przedstawiłeś.
Pokazałeś że jeden czas jest krótszy od drugiego, intuicja
podpowiada, aby wybrać ten krótszy - pomijam fakt że
trzykrotna różnica w czasach, z powodu samej zmiany kolejności 
wyrażeń, już jest podejrzana. Potem do bazy dodaję
jeden rekord, albo nawet tę samą bazę odtwarzam z kopii 
zapasowej i co może się stać? Czasy mogą się zupełnie zmienić,
prawda?


> Do testowania najlepiej używać najwolniejszego komputera
> bo wtedy te czasy są bardzo widoczne, 
Nie zgodzę się, najlepiej użyć warunków najbardziej podobnych do
tych, w jakich baza będzie pracowała. 

> no i testowane pola
> nie powinny mieć indeksów (sprawdzasz tu tylko warunek).
Ale dlaczego w ogóle taki test wykonywać, jeśli potem w
realnym działaniu można indeks założyć?


Pozdrawiam
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194323
Author: Czarek Grądys
Date: Thu, 12 Mar 2015 12:27
12 lines
1577 bytes
W dniu 12.03.2015 o 08:48, nkab@toya.net.pl pisze:

> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
>

Chyba chciałeś napisać: p1 IS NOT NULL


-- 
Cezary Grądys
czarekgr@wa.onet.pl
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194317
Author: nkab
Date: Thu, 12 Mar 2015 15:14
79 lines
5295 bytes
W dniu czwartek, 12 marca 2015 13:22:41 UTC+1 użytkownik M.M. napisał:
> On Thursday, March 12, 2015 at 8:48:10 AM UTC+1, nk...@toya.net.pl wrote:
> > W dniu poniedziałek, 9 marca 2015 12:23:28 UTC+1 użytkownik M.M. napisał:
> > > 
> > > Sorki, ale nadal nie kumam.
> > > Testujesz najpierw:
> > > where x < 5;
> > > A potem:
> > > where x < 5 AND x < 6 OR x < 5;
> > > 
> > > Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
> > > odwrót, że t1>t2.
> >  
> > Po prostu sprawdzasz czy system poprzestaje na sprawdzeniu
> > pierwszego członu warunku i dalej już nie sprawdza np.:
> > 
> > if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> > if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> > 
> > 
> > to co to oznacza? 
> Problem w tym, że to może oznaczać bardzo dużo. Zobacz jak
> dużo dzieje się w trakcie takiego głupiego zapytania. Najpierw
> połączenie z bazą po TCP-IP. Zobacz jak dużo dzieje się na
> tym poziomie: uprawnienia, firewalle, szyfrowanie, kompresja,
> korekcja błędów. Potem zapytanie dostaje się do bazy, i znowu:
> parsowanie, uprawnienia, silnik bazy danych musi sprawdzić czy 
> chociaż są w bazie tabele o podanych nazwach. Potem pracuje
> kompilator i optymalizator zapytania. Optymalizator może
> czasami gromadzić statystyczne dane. Potem bufor systemu
> plików i bufor silnika bazy danych. Sorki, ale ja nadal nie
> umiem wyciągnąć żadnych wniosków z tego co przedstawiłeś.
> Pokazałeś że jeden czas jest krótszy od drugiego, intuicja
> podpowiada, aby wybrać ten krótszy - pomijam fakt że
> trzykrotna różnica w czasach, z powodu samej zmiany kolejności 
> wyrażeń, już jest podejrzana. Potem do bazy dodaję
> jeden rekord, albo nawet tę samą bazę odtwarzam z kopii 
> zapasowej i co może się stać? Czasy mogą się zupełnie zmienić,
> prawda?
> 
> 
> > Do testowania najlepiej używać najwolniejszego komputera
> > bo wtedy te czasy są bardzo widoczne, 
> Nie zgodzę się, najlepiej użyć warunków najbardziej podobnych do
> tych, w jakich baza będzie pracowała. 
> 
> > no i testowane pola
> > nie powinny mieć indeksów (sprawdzasz tu tylko warunek).
> Ale dlaczego w ogóle taki test wykonywać, jeśli potem w
> realnym działaniu można indeks założyć?
> 
> 
> Pozdrawiam

Dlatego od pewnego czasu dałem sobie spokój z czasami wykonywania
bo są tak krótkie, że taka walka trochę mija się z celem.
Te testy wykonywałem za czasów krasnala i wówczas było o co walczyć
bo mój wypasiony komp miał ok 600 MHz na procku.

Pytanie dotyczyło właśnie o kolejność członów w warunku WHERE
i tu moja podpowiedź - od nakrótszego do najwolniejszego oczywiście
jeśli system tak działa, że po nie spełnieniu pierwszego członu
dajmy na to "p1 IS NOT NULL" dalszych już nie sprawdza bo po co.
Kolega pisał, że aż 90% rekordów ma NULLe to chyba lepiej jak
już na wstępie system zrezygnuje ze sprawdzania dalszych członów.

Tu testowanie nie dotyczy pracy sieci ale pracy systemu bazodanowego
na serwerze www. Im sprawniejszy system bazodanowy tym więcej zapytań
obsłuży. Każde zapytanie blokuje bazę na czas jego wykonania.

Tu kolega Marek chciałby aby to user decydował o warunkach w WHERE
i jest pytanie czy sprawdzać programowo zapytanie na obecność
flodów czy nie ma takiej potrzeby bo parser i tak odrzuci powtórzenia.

Na indeksach warunki działają tak samo, indeksy przyspieszają
wyszukiwanie ale tak jak pisałem, czy teraz przy tak krótkich czasach
ma to sens.

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194324
Author: nkab
Date: Thu, 12 Mar 2015 15:20
14 lines
2044 bytes
W dniu czwartek, 12 marca 2015 13:27:02 UTC+1 użytkownik Czarek Grądys napisał:
> W dniu 12.03.2015 o 08:48, nkab@toya.net.pl pisze:
> 
> > if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> > if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> >
> 
> Chyba chciałeś napisać: p1 IS NOT NULL
> 
> 

W MySQL piszę tradycyjnie: p1<>''.

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194325
Author: wloochacz
Date: Thu, 12 Mar 2015 22:41
30 lines
2618 bytes
W dniu 2015-03-12 o 16:20, nkab@toya.net.pl pisze:
> W dniu czwartek, 12 marca 2015 13:27:02 UTC+1 użytkownik Czarek Grądys napisał:
>> W dniu 12.03.2015 o 08:48, nkab@toya.net.pl pisze:
>>
>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
>>>
>>
>> Chyba chciałeś napisać: p1 IS NOT NULL
>
> W MySQL piszę tradycyjnie: p1<>''.
To nie jest żadna tradycja, to gówniano-mysqlowa składnia podobna tylko 
do samej siebie.
Oj będziesz Ty miał bratku mnóstwo kłopotów, kiedy zostaniesz zmuszony 
do pisania pod inną NORMALNĄ bazę danych.

PS.
Szczerze powiem, nie wiedziałem o tym, Kolega mi powiedział...
W mysql przechodzą takie cuda jak dołączanie kolumn do pogrupowanego 
selecta, które to kolumny nie są otoczone żadną funkcją agregującą ani 
nie występują w klauzuli GROUP BY.
Na moje pytanie - "no f..g way, to jaka wartość tam zostanie wypluta?" 
otrzymałem odpowiedź "pierwsza z brzegu" (cokolwiek to znaczy i nie mam 
ochoty tego zgłębiać).
Fantastycznie, prawda? I jak DETERMINISTYCZNIE!

Ty pewnie byś chciał indeks ustawić ;-)

-- 
wloochacz
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194326
Author: IDKrzych
Date: Fri, 13 Mar 2015 00:49
56 lines
3753 bytes
W dniu 2015-03-12 o 23:41, wloochacz pisze:
> W dniu 2015-03-12 o 16:20, nkab@toya.net.pl pisze:
>> W dniu czwartek, 12 marca 2015 13:27:02 UTC+1 użytkownik Czarek Grądys
>> napisał:
>>> W dniu 12.03.2015 o 08:48, nkab@toya.net.pl pisze:
>>>
>>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
>>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
>>>>
>>>
>>> Chyba chciałeś napisać: p1 IS NOT NULL
>>
>> W MySQL piszę tradycyjnie: p1<>''.
> To nie jest żadna tradycja, to gówniano-mysqlowa składnia podobna tylko
> do samej siebie.
> Oj będziesz Ty miał bratku mnóstwo kłopotów, kiedy zostaniesz zmuszony
> do pisania pod inną NORMALNĄ bazę danych.

ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana 
składnia nie działa -> czyli prawidłowo ..
Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?


> PS.
> Szczerze powiem, nie wiedziałem o tym, Kolega mi powiedział...
> W mysql przechodzą takie cuda jak dołączanie kolumn do pogrupowanego
> selecta, które to kolumny nie są otoczone żadną funkcją agregującą ani
> nie występują w klauzuli GROUP BY.
> Na moje pytanie - "no f..g way, to jaka wartość tam zostanie wypluta?"
> otrzymałem odpowiedź "pierwsza z brzegu" (cokolwiek to znaczy i nie mam
> ochoty tego zgłębiać).
> Fantastycznie, prawda? I jak DETERMINISTYCZNIE!
>
> Ty pewnie byś chciał indeks ustawić ;-)
>

A to akurat jest fajne - o ile ma się pełną świadomość istnienia takiego 
zachowania.
Dane które do mnie napływają to przeogromne zestawienia w wielu różnych 
zestawieniach. Są obrzydliwie "tabelaryczne". Codziennie muszę "wróżyć z 
fusów" przy próbie zrozumienia zależności -> możliwość prostego 
grupowania z wypluwaniem powtarzających się wartości wiersza bez zbędnej 
agregacji jest bardzo wygodna i szybka.

Jeżeli ktoś nieumiejętnie wykorzysta tę właściwość to wina leży po 
stronie programisty, a nie "dziwnego fjuczera" :)

Pozdrawiam
-- 
IDKrzych

"Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
- ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
wielowymiarowym,
w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
(S. Lem 1999)
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194327
Author: M.M.
Date: Fri, 13 Mar 2015 04:09
72 lines
4769 bytes
On Friday, March 13, 2015 at 1:49:18 AM UTC+1, IDKrzych wrote:
> W dniu 2015-03-12 o 23:41, wloochacz pisze:
> > W dniu 2015-03-12 o 16:20,  pisze:
> >> W dniu czwartek, 12 marca 2015 13:27:02 UTC+1 użytkownik Czarek Grądys
> >> napisał:
> >>> W dniu 12.03.2015 o 08:48,  pisze:
> >>>
> >>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> >>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> >>>>
> >>>
> >>> Chyba chciałeś napisać: p1 IS NOT NULL
> >>
> >> W MySQL piszę tradycyjnie: p1<>''.
> > To nie jest żadna tradycja, to gówniano-mysqlowa składnia podobna tylko
> > do samej siebie.
> > Oj będziesz Ty miał bratku mnóstwo kłopotów, kiedy zostaniesz zmuszony
> > do pisania pod inną NORMALNĄ bazę danych.
> 
> ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana 
> składnia nie działa -> czyli prawidłowo ..
> Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?
Nie wiem jak jest teraz, ale na pewno u mnie kiedyś działała taka
składnia i na pewno mi jej brakowało w psql. Odpowiadając na wcześniejszy 
post: czy deterministycznie? Ja takiej składni używałem tylko wtedy, gdy
wszystkie wartości były takie same, czyli obojętnie którą wartość
mysql uznał za pierwszą z brzegu, to wynik zapytania był zawsze
taki sam.



> 
> 
> > PS.
> > Szczerze powiem, nie wiedziałem o tym, Kolega mi powiedział...
> > W mysql przechodzą takie cuda jak dołączanie kolumn do pogrupowanego
> > selecta, które to kolumny nie są otoczone żadną funkcją agregującą ani
> > nie występują w klauzuli GROUP BY.
> > Na moje pytanie - "no f..g way, to jaka wartość tam zostanie wypluta?"
> > otrzymałem odpowiedź "pierwsza z brzegu" (cokolwiek to znaczy i nie mam
> > ochoty tego zgłębiać).
> > Fantastycznie, prawda? I jak DETERMINISTYCZNIE!
> >
> > Ty pewnie byś chciał indeks ustawić ;-)
> >
> 
> A to akurat jest fajne - o ile ma się pełną świadomość istnienia takiego 
> zachowania.
> Dane które do mnie napływają to przeogromne zestawienia w wielu różnych 
> zestawieniach. Są obrzydliwie "tabelaryczne". Codziennie muszę "wróżyć z 
> fusów" przy próbie zrozumienia zależności -> możliwość prostego 
> grupowania z wypluwaniem powtarzających się wartości wiersza bez zbędnej 
> agregacji jest bardzo wygodna i szybka.
Aha, czyli chyba używaliśmy tego tak samo?


> Jeżeli ktoś nieumiejętnie wykorzysta tę właściwość to wina leży po 
> stronie programisty, a nie "dziwnego fjuczera" :)
Tak, ale wloochacz też ma rację, że używanie czegoś co nie jest standardowe,
utrwala złe nawyki.


> 
> Pozdrawiam
> -- 
> IDKrzych
> 
> "Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
> - ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
> wielowymiarowym,
> w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
> (S. Lem 1999)
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194318
Author: M.M.
Date: Fri, 13 Mar 2015 04:54
191 lines
9435 bytes
On Thursday, March 12, 2015 at 4:14:39 PM UTC+1, nk...@toya.net.pl wrote:
> W dniu czwartek, 12 marca 2015 13:22:41 UTC+1 użytkownik M.M. napisał:
> > On Thursday, March 12, 2015 at 8:48:10 AM UTC+1, nk...@toya.net.pl wrote:
> > > W dniu poniedziałek, 9 marca 2015 12:23:28 UTC+1 użytkownik M.M. napisał:
> > > > 
> > > > Sorki, ale nadal nie kumam.
> > > > Testujesz najpierw:
> > > > where x < 5;
> > > > A potem:
> > > > where x < 5 AND x < 6 OR x < 5;
> > > > 
> > > > Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
> > > > odwrót, że t1>t2.
> > >  
> > > Po prostu sprawdzasz czy system poprzestaje na sprawdzeniu
> > > pierwszego członu warunku i dalej już nie sprawdza np.:
> > > 
> > > if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> > > if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> > > 
> > > 
> > > to co to oznacza? 
> > Problem w tym, że to może oznaczać bardzo dużo. Zobacz jak
> > dużo dzieje się w trakcie takiego głupiego zapytania. Najpierw
> > połączenie z bazą po TCP-IP. Zobacz jak dużo dzieje się na
> > tym poziomie: uprawnienia, firewalle, szyfrowanie, kompresja,
> > korekcja błędów. Potem zapytanie dostaje się do bazy, i znowu:
> > parsowanie, uprawnienia, silnik bazy danych musi sprawdzić czy 
> > chociaż są w bazie tabele o podanych nazwach. Potem pracuje
> > kompilator i optymalizator zapytania. Optymalizator może
> > czasami gromadzić statystyczne dane. Potem bufor systemu
> > plików i bufor silnika bazy danych. Sorki, ale ja nadal nie
> > umiem wyciągnąć żadnych wniosków z tego co przedstawiłeś.
> > Pokazałeś że jeden czas jest krótszy od drugiego, intuicja
> > podpowiada, aby wybrać ten krótszy - pomijam fakt że
> > trzykrotna różnica w czasach, z powodu samej zmiany kolejności 
> > wyrażeń, już jest podejrzana. Potem do bazy dodaję
> > jeden rekord, albo nawet tę samą bazę odtwarzam z kopii 
> > zapasowej i co może się stać? Czasy mogą się zupełnie zmienić,
> > prawda?
> > 
> > 
> > > Do testowania najlepiej używać najwolniejszego komputera
> > > bo wtedy te czasy są bardzo widoczne, 
> > Nie zgodzę się, najlepiej użyć warunków najbardziej podobnych do
> > tych, w jakich baza będzie pracowała. 
> > 
> > > no i testowane pola
> > > nie powinny mieć indeksów (sprawdzasz tu tylko warunek).
> > Ale dlaczego w ogóle taki test wykonywać, jeśli potem w
> > realnym działaniu można indeks założyć?
> > 
> > 
> > Pozdrawiam
> 
> Dlatego od pewnego czasu dałem sobie spokój z czasami wykonywania
> bo są tak krótkie, że taka walka trochę mija się z celem.
> Te testy wykonywałem za czasów krasnala i wówczas było o co walczyć
> bo mój wypasiony komp miał ok 600 MHz na procku.
Ja może spokoju sobie nie dałem, ale nie liczę na odnalezienie 
jakiejś reguły. Często sprawdzam 2-3 wersje jakiegoś zapytania, ale
zwykle jestem zdziwiony czasami zapytań. Kiedyś, gdy bardzo dużo
optymalizowałem w języku C/C++, to wyrobiłem sobie intucję i
z reguły odgadywałem, które rozwiązanie przyspieszy o 0.5%.
Robiłem 20 poprawek w kodzie i zyskiwałem łączne przyspieszenie 
rzędu 10-30%. A w bazach danych to chyba zawsze jest loteria.
Mam w przybliżeniu takie zapytanie:
select
 tabela.pole1,
 tabela.pole2,
 podzapytanie1,
 podzapytanie2,
 podzapytanie3
from
 tabela
where
 tabela.id > parametr
order by 
 tabela.id
limit 1000.

Dodam, że podzapytania są skomplikowane, np. mają kolejne 
podzapytania. Zapytaniem tym, zwiększając parametr w każdej
iteracji, wyciągam z bazy po 1000 'rekordów'. Zapytanie
działa rewlacyjnie około 20 razy. 20 zapytań, czyli wyciągnięcie
20tys rekordów, trwa może 20 sekund. Potem nagle zapytanie 21
trwa np. 120 sekund. I nie mam pojęcia co zrobić.

W drugim rozwiązaniu dałem coś takiego:
select
 tabela.pole1,
 tabela.pole2,
 podzapytanie1,
 podzapytanie2,
 podzapytanie3
from
 tabela
where
 tabela.id in (id1,id2,...id1000)

Działało wolniej niż pierwsze, ale nie było tego nagłego 120
sekundowego laga. Potem spróbowałem jeszcze jedną wersję:

select
 tabela.pole1,
 tabela.pole2,
 podzapytanie1,
 podzapytanie2,
 podzapytanie3
from
 tabela
where
 tabela.id <= max AND tabela.id > min
 
To ostatnie działa najlepiej. Oczywiście to i powyższe 
zapytanie wymaga dodatkowego zapytania które wyciągnie z
bazy ograniczenia na tabela.id.

Ta ostatnia wersja wymaga mniej/więcej:

select
 max(tabela.id),
from (
select
 tabela.id,
from
 tabela
where
 tabela.id > prev_max
order by 
 tabela.id
limit 1000.
);

Czyli ta ostatnia wersja to nic innego, jak rozbicie jednego
dużego zapytania na dwa małe. A jednak nie ma tego nagłego
spowolnienia o 60 razy! Mnie ręce opadają, dlaczego baza
sobie nie radzi?



> Pytanie dotyczyło właśnie o kolejność członów w warunku WHERE
> i tu moja podpowiedź - od nakrótszego do najwolniejszego oczywiście
> jeśli system tak działa, że po nie spełnieniu pierwszego członu
> dajmy na to "p1 IS NOT NULL" dalszych już nie sprawdza bo po co.
> Kolega pisał, że aż 90% rekordów ma NULLe to chyba lepiej jak
> już na wstępie system zrezygnuje ze sprawdzania dalszych członów.
W sumie racja, jeśli pola w danym silniku są zorganizowane jako 
tabele kolumnowe, to nie musi dociągać pozostałych danych. Można
obliczenia wykonywane w klauzuli where przyspieszyć ze 1.5 raza.
A to w niektórych przypadkach może dać zysku z 10% na całym
zapytaniu. Pytanie czy warto się bić o te 10%?


> Tu testowanie nie dotyczy pracy sieci ale pracy systemu bazodanowego
> na serwerze www. Im sprawniejszy system bazodanowy tym więcej zapytań
> obsłuży. Każde zapytanie blokuje bazę na czas jego wykonania.
Tak, ale zobacz. Operacje na danych trwają np. 0.1 sekundy. A nawiązanie
polączenia, transfer, parsering zapytania, testy uprawnień, logowanie,
budowanie statystyk przez optymalizator, trwa np. 1s. Czyli łączny
czas to 1.1s. Przyspieszysz operację na danych o 10%, czyli całość
trwa 1.09s. Więc przyspieszenie jakie w praktyce widzisz to 1%. Pytanie
czy w ogóle warto się brać za próbę takiego przyspieszania? 

Druga sprawa, baza danych to nie jest asembler wykonywany na określonym
CPU. W każdej chwili, np. po dodaniu nowej kolumny, albo wręcz po
dodaniu nowego rekordu, optymalizator może zapytanie wykonać 
zupełnie inaczej. W wyniku tego, ciężko uzyskane przyspieszenie, nagle
zamieni się w spowolnienie. Generalnie z Tobą się zgadzam, ale 
mam wątpliwości, czy w ogóle warto się brać za taki tuning?


> Tu kolega Marek chciałby aby to user decydował o warunkach w WHERE
> i jest pytanie czy sprawdzać programowo zapytanie na obecność
> flodów czy nie ma takiej potrzeby bo parser i tak odrzuci powtórzenia.
To wiedzą tylko osoby które znają silnik bazy od podszewki. Myślę, że
optymalizator raz zachowa się tak, a drugi raz inaczej. A po wgraniu
nowej wersji silnika, albo po użyciu dysku SSD, może wszystko
ulec kolejnej zmianie.


> Na indeksach warunki działają tak samo, indeksy przyspieszają
> wyszukiwanie ale tak jak pisałem, czy teraz przy tak krótkich czasach
> ma to sens.
Moim zdaniem nie działają tak samo. Jeśli indeks pasuje do warunku, to
warunek w ogóle nie jest sprawdzany. W wyniku przeszukiwania b-tree
od razu dochodzimy do rekordów spełniających warunek. W przypadku
indeksu w ogóle nie ma sensu testowanie kolejności - przynajmniej
ja bym nie testował.

Pozdrawiam
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194319
Author: artiun
Date: Sat, 14 Mar 2015 05:02
203 lines
10196 bytes
W dniu 2015-03-13 o 05:54, M.M. pisze:
> On Thursday, March 12, 2015 at 4:14:39 PM UTC+1, nk...@toya.net.pl wrote:
>> W dniu czwartek, 12 marca 2015 13:22:41 UTC+1 użytkownik M.M. napisał:
>>> On Thursday, March 12, 2015 at 8:48:10 AM UTC+1, nk...@toya.net.pl wrote:
>>>> W dniu poniedziałek, 9 marca 2015 12:23:28 UTC+1 użytkownik M.M. napisał:
>>>>>
>>>>> Sorki, ale nadal nie kumam.
>>>>> Testujesz najpierw:
>>>>> where x < 5;
>>>>> A potem:
>>>>> where x < 5 AND x < 6 OR x < 5;
>>>>>
>>>>> Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
>>>>> odwrót, że t1>t2.
>>>>
>>>> Po prostu sprawdzasz czy system poprzestaje na sprawdzeniu
>>>> pierwszego członu warunku i dalej już nie sprawdza np.:
>>>>
>>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
>>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
>>>>
>>>>
>>>> to co to oznacza?
>>> Problem w tym, że to może oznaczać bardzo dużo. Zobacz jak
>>> dużo dzieje się w trakcie takiego głupiego zapytania. Najpierw
>>> połączenie z bazą po TCP-IP. Zobacz jak dużo dzieje się na
>>> tym poziomie: uprawnienia, firewalle, szyfrowanie, kompresja,
>>> korekcja błędów. Potem zapytanie dostaje się do bazy, i znowu:
>>> parsowanie, uprawnienia, silnik bazy danych musi sprawdzić czy
>>> chociaż są w bazie tabele o podanych nazwach. Potem pracuje
>>> kompilator i optymalizator zapytania. Optymalizator może
>>> czasami gromadzić statystyczne dane. Potem bufor systemu
>>> plików i bufor silnika bazy danych. Sorki, ale ja nadal nie
>>> umiem wyciągnąć żadnych wniosków z tego co przedstawiłeś.
>>> Pokazałeś że jeden czas jest krótszy od drugiego, intuicja
>>> podpowiada, aby wybrać ten krótszy - pomijam fakt że
>>> trzykrotna różnica w czasach, z powodu samej zmiany kolejności
>>> wyrażeń, już jest podejrzana. Potem do bazy dodaję
>>> jeden rekord, albo nawet tę samą bazę odtwarzam z kopii
>>> zapasowej i co może się stać? Czasy mogą się zupełnie zmienić,
>>> prawda?
>>>
>>>
>>>> Do testowania najlepiej używać najwolniejszego komputera
>>>> bo wtedy te czasy są bardzo widoczne,
>>> Nie zgodzę się, najlepiej użyć warunków najbardziej podobnych do
>>> tych, w jakich baza będzie pracowała.
>>>
>>>> no i testowane pola
>>>> nie powinny mieć indeksów (sprawdzasz tu tylko warunek).
>>> Ale dlaczego w ogóle taki test wykonywać, jeśli potem w
>>> realnym działaniu można indeks założyć?
>>>
>>>
>>> Pozdrawiam
>>
>> Dlatego od pewnego czasu dałem sobie spokój z czasami wykonywania
>> bo są tak krótkie, że taka walka trochę mija się z celem.
>> Te testy wykonywałem za czasów krasnala i wówczas było o co walczyć
>> bo mój wypasiony komp miał ok 600 MHz na procku.
> Ja może spokoju sobie nie dałem, ale nie liczę na odnalezienie
> jakiejś reguły. Często sprawdzam 2-3 wersje jakiegoś zapytania, ale
> zwykle jestem zdziwiony czasami zapytań. Kiedyś, gdy bardzo dużo
> optymalizowałem w języku C/C++, to wyrobiłem sobie intucję i
> z reguły odgadywałem, które rozwiązanie przyspieszy o 0.5%.
> Robiłem 20 poprawek w kodzie i zyskiwałem łączne przyspieszenie
> rzędu 10-30%. A w bazach danych to chyba zawsze jest loteria.
> Mam w przybliżeniu takie zapytanie:
> select
>   tabela.pole1,
>   tabela.pole2,
>   podzapytanie1,
>   podzapytanie2,
>   podzapytanie3
> from
>   tabela
> where
>   tabela.id > parametr
> order by
>   tabela.id
> limit 1000.
>
> Dodam, że podzapytania są skomplikowane, np. mają kolejne
> podzapytania. Zapytaniem tym, zwiększając parametr w każdej
> iteracji, wyciągam z bazy po 1000 'rekordów'. Zapytanie
> działa rewlacyjnie około 20 razy. 20 zapytań, czyli wyciągnięcie
> 20tys rekordów, trwa może 20 sekund. Potem nagle zapytanie 21
> trwa np. 120 sekund. I nie mam pojęcia co zrobić.
>
> W drugim rozwiązaniu dałem coś takiego:
> select
>   tabela.pole1,
>   tabela.pole2,
>   podzapytanie1,
>   podzapytanie2,
>   podzapytanie3
> from
>   tabela
> where
>   tabela.id in (id1,id2,...id1000)
>
> Działało wolniej niż pierwsze, ale nie było tego nagłego 120
> sekundowego laga. Potem spróbowałem jeszcze jedną wersję:
>
> select
>   tabela.pole1,
>   tabela.pole2,
>   podzapytanie1,
>   podzapytanie2,
>   podzapytanie3
> from
>   tabela
> where
>   tabela.id <= max AND tabela.id > min
>
> To ostatnie działa najlepiej. Oczywiście to i powyższe
> zapytanie wymaga dodatkowego zapytania które wyciągnie z
> bazy ograniczenia na tabela.id.
>
> Ta ostatnia wersja wymaga mniej/więcej:
>
> select
>   max(tabela.id),
> from (
> select
>   tabela.id,
> from
>   tabela
> where
>   tabela.id > prev_max
> order by
>   tabela.id
> limit 1000.
> );
>
> Czyli ta ostatnia wersja to nic innego, jak rozbicie jednego
> dużego zapytania na dwa małe. A jednak nie ma tego nagłego
> spowolnienia o 60 razy! Mnie ręce opadają, dlaczego baza
> sobie nie radzi?
>
Jeśli chcesz można coś spierdolić, to przykład dobry. Tabela (parę mln 
rekordów) i po polu nie indeksowanym - puść jej max. I teraz wytłumacz 
pracodawcy.
Mam nadzieję, że to tylko przykład.
>
>
>> Pytanie dotyczyło właśnie o kolejność członów w warunku WHERE
>> i tu moja podpowiedź - od nakrótszego do najwolniejszego oczywiście
>> jeśli system tak działa, że po nie spełnieniu pierwszego członu
>> dajmy na to "p1 IS NOT NULL" dalszych już nie sprawdza bo po co.
>> Kolega pisał, że aż 90% rekordów ma NULLe to chyba lepiej jak
>> już na wstępie system zrezygnuje ze sprawdzania dalszych członów.
> W sumie racja, jeśli pola w danym silniku są zorganizowane jako
> tabele kolumnowe, to nie musi dociągać pozostałych danych. Można
> obliczenia wykonywane w klauzuli where przyspieszyć ze 1.5 raza.
> A to w niektórych przypadkach może dać zysku z 10% na całym
> zapytaniu. Pytanie czy warto się bić o te 10%?
>
>
>> Tu testowanie nie dotyczy pracy sieci ale pracy systemu bazodanowego
>> na serwerze www. Im sprawniejszy system bazodanowy tym więcej zapytań
>> obsłuży. Każde zapytanie blokuje bazę na czas jego wykonania.
> Tak, ale zobacz. Operacje na danych trwają np. 0.1 sekundy. A nawiązanie
> polączenia, transfer, parsering zapytania, testy uprawnień, logowanie,
> budowanie statystyk przez optymalizator, trwa np. 1s. Czyli łączny
> czas to 1.1s. Przyspieszysz operację na danych o 10%, czyli całość
> trwa 1.09s. Więc przyspieszenie jakie w praktyce widzisz to 1%. Pytanie
> czy w ogóle warto się brać za próbę takiego przyspieszania?
>
> Druga sprawa, baza danych to nie jest asembler wykonywany na określonym
> CPU. W każdej chwili, np. po dodaniu nowej kolumny, albo wręcz po
> dodaniu nowego rekordu, optymalizator może zapytanie wykonać
> zupełnie inaczej. W wyniku tego, ciężko uzyskane przyspieszenie, nagle
> zamieni się w spowolnienie. Generalnie z Tobą się zgadzam, ale
> mam wątpliwości, czy w ogóle warto się brać za taki tuning?
>
>
>> Tu kolega Marek chciałby aby to user decydował o warunkach w WHERE
>> i jest pytanie czy sprawdzać programowo zapytanie na obecność
>> flodów czy nie ma takiej potrzeby bo parser i tak odrzuci powtórzenia..
> To wiedzą tylko osoby które znają silnik bazy od podszewki. Myślę, że
> optymalizator raz zachowa się tak, a drugi raz inaczej. A po wgraniu
> nowej wersji silnika, albo po użyciu dysku SSD, może wszystko
> ulec kolejnej zmianie.
>
>
>> Na indeksach warunki działają tak samo, indeksy przyspieszają
>> wyszukiwanie ale tak jak pisałem, czy teraz przy tak krótkich czasach
>> ma to sens.
> Moim zdaniem nie działają tak samo. Jeśli indeks pasuje do warunku, to
> warunek w ogóle nie jest sprawdzany. W wyniku przeszukiwania b-tree
> od razu dochodzimy do rekordów spełniających warunek. W przypadku
> indeksu w ogóle nie ma sensu testowanie kolejności - przynajmniej
> ja bym nie testował.
>
> Pozdrawiam
>


-- 
Artur
0 weeks 1 day 8 hours 40 minutes 37 seconds and 336 milliseconds.
"pl.comp.bazy-danych"
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194328
Author: artiun
Date: Sat, 14 Mar 2015 05:13
84 lines
5429 bytes
W dniu 2015-03-13 o 05:09, M.M. pisze:
> On Friday, March 13, 2015 at 1:49:18 AM UTC+1, IDKrzych wrote:
>> W dniu 2015-03-12 o 23:41, wloochacz pisze:
>>> W dniu 2015-03-12 o 16:20,  pisze:
>>>> W dniu czwartek, 12 marca 2015 13:27:02 UTC+1 użytkownik Czarek Grądys
>>>> napisał:
>>>>> W dniu 12.03.2015 o 08:48,  pisze:
>>>>>
>>>>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
>>>>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
>>>>>>
>>>>>
>>>>> Chyba chciałeś napisać: p1 IS NOT NULL
>>>>
>>>> W MySQL piszę tradycyjnie: p1<>''.
>>> To nie jest żadna tradycja, to gówniano-mysqlowa składnia podobna tylko
>>> do samej siebie.
>>> Oj będziesz Ty miał bratku mnóstwo kłopotów, kiedy zostaniesz zmuszony
>>> do pisania pod inną NORMALNĄ bazę danych.
>>
>> ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana
>> składnia nie działa -> czyli prawidłowo ..
>> Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?
> Nie wiem jak jest teraz, ale na pewno u mnie kiedyś działała taka
> składnia i na pewno mi jej brakowało w psql. Odpowiadając na wcześniejszy
> post: czy deterministycznie? Ja takiej składni używałem tylko wtedy, gdy
> wszystkie wartości były takie same, czyli obojętnie którą wartość
> mysql uznał za pierwszą z brzegu, to wynik zapytania był zawsze
> taki sam.
>
>
1. null nigdy nie był traktowany jako wartość pusta stringu (głupota, 
chociaż bywało - to zależało od bazy)
2. zasady matematyczne (+-)(*/) i zbiory
3. jeśli baza jest zła (to dlaczego używa ją tyle firm)
>
>>
>>
>>> PS.
>>> Szczerze powiem, nie wiedziałem o tym, Kolega mi powiedział...
>>> W mysql przechodzą takie cuda jak dołączanie kolumn do pogrupowanego
>>> selecta, które to kolumny nie są otoczone żadną funkcją agregującą ani
>>> nie występują w klauzuli GROUP BY.
>>> Na moje pytanie - "no f..g way, to jaka wartość tam zostanie wypluta?"
>>> otrzymałem odpowiedź "pierwsza z brzegu" (cokolwiek to znaczy i nie mam
>>> ochoty tego zgłębiać).
>>> Fantastycznie, prawda? I jak DETERMINISTYCZNIE!
>>>
>>> Ty pewnie byś chciał indeks ustawić ;-)
>>>
>>
>> A to akurat jest fajne - o ile ma się pełną świadomość istnienia takiego
>> zachowania.
>> Dane które do mnie napływają to przeogromne zestawienia w wielu różnych
>> zestawieniach. Są obrzydliwie "tabelaryczne". Codziennie muszę "wróżyć z
>> fusów" przy próbie zrozumienia zależności -> możliwość prostego
>> grupowania z wypluwaniem powtarzających się wartości wiersza bez zbędnej
>> agregacji jest bardzo wygodna i szybka.
> Aha, czyli chyba używaliśmy tego tak samo?
>
>
>> Jeżeli ktoś nieumiejętnie wykorzysta tę właściwość to wina leży po
>> stronie programisty, a nie "dziwnego fjuczera" :)
> Tak, ale wloochacz też ma rację, że używanie czegoś co nie jest standardowe,
> utrwala złe nawyki.
>
>
>>
>> Pozdrawiam
>> --
>> IDKrzych
>>
>> "Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
>> - ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
>> wielowymiarowym,
>> w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
>> (S. Lem 1999)
>


-- 
Artur
0 weeks 1 day 8 hours 55 minutes 17 seconds and 444 milliseconds.
"pl.comp.bazy-danych"
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194321
Author: Adam
Date: Sat, 14 Mar 2015 12:38
38 lines
3094 bytes
W dniu 2015-03-13 o 05:54, M.M. pisze:
> On Thursday, March 12, 2015 at 4:14:39 PM UTC+1, nk...@toya.net.pl wrote:
>>(...)
>> Pytanie dotyczyło właśnie o kolejność członów w warunku WHERE
>> i tu moja podpowiedź - od nakrótszego do najwolniejszego oczywiście
>> jeśli system tak działa, że po nie spełnieniu pierwszego członu
>> dajmy na to "p1 IS NOT NULL" dalszych już nie sprawdza bo po co.
>> Kolega pisał, że aż 90% rekordów ma NULLe to chyba lepiej jak
>> już na wstępie system zrezygnuje ze sprawdzania dalszych członów.
> W sumie racja, jeśli pola w danym silniku są zorganizowane jako
> tabele kolumnowe, to nie musi dociągać pozostałych danych. Można
> obliczenia wykonywane w klauzuli where przyspieszyć ze 1.5 raza.
> A to w niektórych przypadkach może dać zysku z 10% na całym
> zapytaniu. Pytanie czy warto się bić o te 10%?
> (...)

Patrz szerzej.
Przy jednym kliencie może to być 10%.
Jeśli jest to baza danych "firmowa" (czyli obsługująca magazyn, handel, 
kadry, itd.) to klientów (równoczesnych) może być kilkudziesięciu, a 
zapytać setki czy tysiące.
Jeśli jest to sklep internetowy, to klientów mogą być setki.
Wtedy każde 10% robi radykalną różnicę. A jeśli się "umie" robić selecty 
na widokach (w MSSQL), to chyba też jest duży plus.

Ja czasami widzę coś w rodzaju:
select (...) where (...) and (...) and 1=1

Co ciekawe, bez warunku "and 1=1" odpowiedź idzie dłużej. Dziwne, gdyż 
teoretycznie każdy nowy warunek powinien przedłużyć odpowiedź. Ważne też 
jest, w którym miejscu siedzi owo 1=1.
Ale tu już trzeba dogłębnie znać silnik.


-- 
Pozdrawiam.

Adam
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194320
Author: M.M.
Date: Sat, 14 Mar 2015 15:23
213 lines
10882 bytes
On Saturday, March 14, 2015 at 6:42:58 AM UTC+1, artiun wrote:
> W dniu 2015-03-13 o 05:54, M.M. pisze:
> > On Thursday, March 12, 2015 at 4:14:39 PM UTC+1, nk...@toya.net.pl wrote:
> >> W dniu czwartek, 12 marca 2015 13:22:41 UTC+1 użytkownik M.M. napisał:
> >>> On Thursday, March 12, 2015 at 8:48:10 AM UTC+1, nk...@toya.net.pl wrote:
> >>>> W dniu poniedziałek, 9 marca 2015 12:23:28 UTC+1 użytkownik M.M. napisał:
> >>>>>
> >>>>> Sorki, ale nadal nie kumam.
> >>>>> Testujesz najpierw:
> >>>>> where x < 5;
> >>>>> A potem:
> >>>>> where x < 5 AND x < 6 OR x < 5;
> >>>>>
> >>>>> Wyszły Ci czasy t1 i t2. Załóżmy że t1<t2 to co wywnioskujesz? I na
> >>>>> odwrót, że t1>t2.
> >>>>
> >>>> Po prostu sprawdzasz czy system poprzestaje na sprawdzeniu
> >>>> pierwszego członu warunku i dalej już nie sprawdza np.:
> >>>>
> >>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> >>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> >>>>
> >>>>
> >>>> to co to oznacza?
> >>> Problem w tym, że to może oznaczać bardzo dużo. Zobacz jak
> >>> dużo dzieje się w trakcie takiego głupiego zapytania. Najpierw
> >>> połączenie z bazą po TCP-IP. Zobacz jak dużo dzieje się na
> >>> tym poziomie: uprawnienia, firewalle, szyfrowanie, kompresja,
> >>> korekcja błędów. Potem zapytanie dostaje się do bazy, i znowu:
> >>> parsowanie, uprawnienia, silnik bazy danych musi sprawdzić czy
> >>> chociaż są w bazie tabele o podanych nazwach. Potem pracuje
> >>> kompilator i optymalizator zapytania. Optymalizator może
> >>> czasami gromadzić statystyczne dane. Potem bufor systemu
> >>> plików i bufor silnika bazy danych. Sorki, ale ja nadal nie
> >>> umiem wyciągnąć żadnych wniosków z tego co przedstawiłeś.
> >>> Pokazałeś że jeden czas jest krótszy od drugiego, intuicja
> >>> podpowiada, aby wybrać ten krótszy - pomijam fakt że
> >>> trzykrotna różnica w czasach, z powodu samej zmiany kolejności
> >>> wyrażeń, już jest podejrzana. Potem do bazy dodaję
> >>> jeden rekord, albo nawet tę samą bazę odtwarzam z kopii
> >>> zapasowej i co może się stać? Czasy mogą się zupełnie zmienić,
> >>> prawda?
> >>>
> >>>
> >>>> Do testowania najlepiej używać najwolniejszego komputera
> >>>> bo wtedy te czasy są bardzo widoczne,
> >>> Nie zgodzę się, najlepiej użyć warunków najbardziej podobnych do
> >>> tych, w jakich baza będzie pracowała.
> >>>
> >>>> no i testowane pola
> >>>> nie powinny mieć indeksów (sprawdzasz tu tylko warunek).
> >>> Ale dlaczego w ogóle taki test wykonywać, jeśli potem w
> >>> realnym działaniu można indeks założyć?
> >>>
> >>>
> >>> Pozdrawiam
> >>
> >> Dlatego od pewnego czasu dałem sobie spokój z czasami wykonywania
> >> bo są tak krótkie, że taka walka trochę mija się z celem.
> >> Te testy wykonywałem za czasów krasnala i wówczas było o co walczyć
> >> bo mój wypasiony komp miał ok 600 MHz na procku.
> > Ja może spokoju sobie nie dałem, ale nie liczę na odnalezienie
> > jakiejś reguły. Często sprawdzam 2-3 wersje jakiegoś zapytania, ale
> > zwykle jestem zdziwiony czasami zapytań. Kiedyś, gdy bardzo dużo
> > optymalizowałem w języku C/C++, to wyrobiłem sobie intucję i
> > z reguły odgadywałem, które rozwiązanie przyspieszy o 0.5%.
> > Robiłem 20 poprawek w kodzie i zyskiwałem łączne przyspieszenie
> > rzędu 10-30%. A w bazach danych to chyba zawsze jest loteria.
> > Mam w przybliżeniu takie zapytanie:
> > select
> >   tabela.pole1,
> >   tabela.pole2,
> >   podzapytanie1,
> >   podzapytanie2,
> >   podzapytanie3
> > from
> >   tabela
> > where
> >   tabela.id > parametr
> > order by
> >   tabela.id
> > limit 1000.
> >
> > Dodam, że podzapytania są skomplikowane, np. mają kolejne
> > podzapytania. Zapytaniem tym, zwiększając parametr w każdej
> > iteracji, wyciągam z bazy po 1000 'rekordów'. Zapytanie
> > działa rewlacyjnie około 20 razy. 20 zapytań, czyli wyciągnięcie
> > 20tys rekordów, trwa może 20 sekund. Potem nagle zapytanie 21
> > trwa np. 120 sekund. I nie mam pojęcia co zrobić.
> >
> > W drugim rozwiązaniu dałem coś takiego:
> > select
> >   tabela.pole1,
> >   tabela.pole2,
> >   podzapytanie1,
> >   podzapytanie2,
> >   podzapytanie3
> > from
> >   tabela
> > where
> >   tabela.id in (id1,id2,...id1000)
> >
> > Działało wolniej niż pierwsze, ale nie było tego nagłego 120
> > sekundowego laga. Potem spróbowałem jeszcze jedną wersję:
> >
> > select
> >   tabela.pole1,
> >   tabela.pole2,
> >   podzapytanie1,
> >   podzapytanie2,
> >   podzapytanie3
> > from
> >   tabela
> > where
> >   tabela.id <= max AND tabela.id > min
> >
> > To ostatnie działa najlepiej. Oczywiście to i powyższe
> > zapytanie wymaga dodatkowego zapytania które wyciągnie z
> > bazy ograniczenia na tabela.id.
> >
> > Ta ostatnia wersja wymaga mniej/więcej:
> >
> > select
> >   max(tabela.id),
> > from (
> > select
> >   tabela.id,
> > from
> >   tabela
> > where
> >   tabela.id > prev_max
> > order by
> >   tabela.id
> > limit 1000.
> > );
> >
> > Czyli ta ostatnia wersja to nic innego, jak rozbicie jednego
> > dużego zapytania na dwa małe. A jednak nie ma tego nagłego
> > spowolnienia o 60 razy! Mnie ręce opadają, dlaczego baza
> > sobie nie radzi?
> >
> Jeśli chcesz można coś spierdolić, to przykład dobry. Tabela (parę mln 
> rekordów) i po polu nie indeksowanym - puść jej max. I teraz wytłumacz 
> pracodawcy.
> Mam nadzieję, że to tylko przykład.
Sorki, ale chodziło o coś zupełnie innego niż o to czy
pole jest indeksowanie czy nie. Chodziło o 20 bardzo
podobnych zapytań, różniących się tylko przedziałem i
o to że optymalizator z 19-toma sobie radzi doskonale a
z 20-tym nagle nie potrafi! - obojętnie czy indeksy są 
czy ich nie ma. 



> >
> >
> >> Pytanie dotyczyło właśnie o kolejność członów w warunku WHERE
> >> i tu moja podpowiedź - od nakrótszego do najwolniejszego oczywiście
> >> jeśli system tak działa, że po nie spełnieniu pierwszego członu
> >> dajmy na to "p1 IS NOT NULL" dalszych już nie sprawdza bo po co.
> >> Kolega pisał, że aż 90% rekordów ma NULLe to chyba lepiej jak
> >> już na wstępie system zrezygnuje ze sprawdzania dalszych członów.
> > W sumie racja, jeśli pola w danym silniku są zorganizowane jako
> > tabele kolumnowe, to nie musi dociągać pozostałych danych. Można
> > obliczenia wykonywane w klauzuli where przyspieszyć ze 1.5 raza.
> > A to w niektórych przypadkach może dać zysku z 10% na całym
> > zapytaniu. Pytanie czy warto się bić o te 10%?
> >
> >
> >> Tu testowanie nie dotyczy pracy sieci ale pracy systemu bazodanowego
> >> na serwerze www. Im sprawniejszy system bazodanowy tym więcej zapytań
> >> obsłuży. Każde zapytanie blokuje bazę na czas jego wykonania.
> > Tak, ale zobacz. Operacje na danych trwają np. 0.1 sekundy. A nawiązanie
> > polączenia, transfer, parsering zapytania, testy uprawnień, logowanie,
> > budowanie statystyk przez optymalizator, trwa np. 1s. Czyli łączny
> > czas to 1.1s. Przyspieszysz operację na danych o 10%, czyli całość
> > trwa 1.09s. Więc przyspieszenie jakie w praktyce widzisz to 1%. Pytanie
> > czy w ogóle warto się brać za próbę takiego przyspieszania?
> >
> > Druga sprawa, baza danych to nie jest asembler wykonywany na określonym
> > CPU. W każdej chwili, np. po dodaniu nowej kolumny, albo wręcz po
> > dodaniu nowego rekordu, optymalizator może zapytanie wykonać
> > zupełnie inaczej. W wyniku tego, ciężko uzyskane przyspieszenie, nagle
> > zamieni się w spowolnienie. Generalnie z Tobą się zgadzam, ale
> > mam wątpliwości, czy w ogóle warto się brać za taki tuning?
> >
> >
> >> Tu kolega Marek chciałby aby to user decydował o warunkach w WHERE
> >> i jest pytanie czy sprawdzać programowo zapytanie na obecność
> >> flodów czy nie ma takiej potrzeby bo parser i tak odrzuci powtórzenia..
> > To wiedzą tylko osoby które znają silnik bazy od podszewki. Myślę, że
> > optymalizator raz zachowa się tak, a drugi raz inaczej. A po wgraniu
> > nowej wersji silnika, albo po użyciu dysku SSD, może wszystko
> > ulec kolejnej zmianie.
> >
> >
> >> Na indeksach warunki działają tak samo, indeksy przyspieszają
> >> wyszukiwanie ale tak jak pisałem, czy teraz przy tak krótkich czasach
> >> ma to sens.
> > Moim zdaniem nie działają tak samo. Jeśli indeks pasuje do warunku, to
> > warunek w ogóle nie jest sprawdzany. W wyniku przeszukiwania b-tree
> > od razu dochodzimy do rekordów spełniających warunek. W przypadku
> > indeksu w ogóle nie ma sensu testowanie kolejności - przynajmniej
> > ja bym nie testował.
> >
> > Pozdrawiam
> >
> 
> 
> -- 
> Artur
> 0 weeks 1 day 8 hours 40 minutes 37 seconds and 336 milliseconds.
> "pl.comp.bazy-danych"
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194329
Author: M.M.
Date: Sat, 14 Mar 2015 15:25
88 lines
5537 bytes
On Saturday, March 14, 2015 at 6:43:12 AM UTC+1, artiun wrote:
> W dniu 2015-03-13 o 05:09, M.M. pisze:
> > On Friday, March 13, 2015 at 1:49:18 AM UTC+1, IDKrzych wrote:
> >> W dniu 2015-03-12 o 23:41, wloochacz pisze:
> >>> W dniu 2015-03-12 o 16:20,  pisze:
> >>>> W dniu czwartek, 12 marca 2015 13:27:02 UTC+1 użytkownik Czarek Grądys
> >>>> napisał:
> >>>>> W dniu 12.03.2015 o 08:48,  pisze:
> >>>>>
> >>>>>> if (p1<>NULL and p2=p3)  czas wykonania ~0,03 sek
> >>>>>> if (p2=p3 and p1<>NULL) czas wykonania ~0,08 sek
> >>>>>>
> >>>>>
> >>>>> Chyba chciałeś napisać: p1 IS NOT NULL
> >>>>
> >>>> W MySQL piszę tradycyjnie: p1<>''.
> >>> To nie jest żadna tradycja, to gówniano-mysqlowa składnia podobna tylko
> >>> do samej siebie.
> >>> Oj będziesz Ty miał bratku mnóstwo kłopotów, kiedy zostaniesz zmuszony
> >>> do pisania pod inną NORMALNĄ bazę danych.
> >>
> >> ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana
> >> składnia nie działa -> czyli prawidłowo ..
> >> Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?
> > Nie wiem jak jest teraz, ale na pewno u mnie kiedyś działała taka
> > składnia i na pewno mi jej brakowało w psql. Odpowiadając na wcześniejszy
> > post: czy deterministycznie? Ja takiej składni używałem tylko wtedy, gdy
> > wszystkie wartości były takie same, czyli obojętnie którą wartość
> > mysql uznał za pierwszą z brzegu, to wynik zapytania był zawsze
> > taki sam.
> >
> >
> 1. null nigdy nie był traktowany jako wartość pusta stringu (głupota, 
> chociaż bywało - to zależało od bazy)
> 2. zasady matematyczne (+-)(*/) i zbiory
> 3. jeśli baza jest zła (to dlaczego używa ją tyle firm)
Nie o to chodziło. Chodziło o pole na którego nie ma
w group by.

> >
> >>
> >>
> >>> PS.
> >>> Szczerze powiem, nie wiedziałem o tym, Kolega mi powiedział...
> >>> W mysql przechodzą takie cuda jak dołączanie kolumn do pogrupowanego
> >>> selecta, które to kolumny nie są otoczone żadną funkcją agregującą ani
> >>> nie występują w klauzuli GROUP BY.
> >>> Na moje pytanie - "no f..g way, to jaka wartość tam zostanie wypluta?"
> >>> otrzymałem odpowiedź "pierwsza z brzegu" (cokolwiek to znaczy i nie mam
> >>> ochoty tego zgłębiać).
> >>> Fantastycznie, prawda? I jak DETERMINISTYCZNIE!
> >>>
> >>> Ty pewnie byś chciał indeks ustawić ;-)
> >>>
> >>
> >> A to akurat jest fajne - o ile ma się pełną świadomość istnienia takiego
> >> zachowania.
> >> Dane które do mnie napływają to przeogromne zestawienia w wielu różnych
> >> zestawieniach. Są obrzydliwie "tabelaryczne". Codziennie muszę "wróżyć z
> >> fusów" przy próbie zrozumienia zależności -> możliwość prostego
> >> grupowania z wypluwaniem powtarzających się wartości wiersza bez zbędnej
> >> agregacji jest bardzo wygodna i szybka.
> > Aha, czyli chyba używaliśmy tego tak samo?
> >
> >
> >> Jeżeli ktoś nieumiejętnie wykorzysta tę właściwość to wina leży po
> >> stronie programisty, a nie "dziwnego fjuczera" :)
> > Tak, ale wloochacz też ma rację, że używanie czegoś co nie jest standardowe,
> > utrwala złe nawyki.
> >
> >
> >>
> >> Pozdrawiam
> >> --
> >> IDKrzych
> >>
> >> "Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
> >> - ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
> >> wielowymiarowym,
> >> w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
> >> (S. Lem 1999)
> >
> 
> 
> -- 
> Artur
> 0 weeks 1 day 8 hours 55 minutes 17 seconds and 444 milliseconds.
> "pl.comp.bazy-danych"
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194322
Author: M.M.
Date: Sat, 14 Mar 2015 15:30
54 lines
4164 bytes
On Saturday, March 14, 2015 at 1:38:47 PM UTC+1, Adam wrote:
> W dniu 2015-03-13 o 05:54, M.M. pisze:
> > On Thursday, March 12, 2015 at 4:14:39 PM UTC+1, nk...@toya.net.pl wrote:
> >>(...)
> >> Pytanie dotyczyło właśnie o kolejność członów w warunku WHERE
> >> i tu moja podpowiedź - od nakrótszego do najwolniejszego oczywiście
> >> jeśli system tak działa, że po nie spełnieniu pierwszego członu
> >> dajmy na to "p1 IS NOT NULL" dalszych już nie sprawdza bo po co.
> >> Kolega pisał, że aż 90% rekordów ma NULLe to chyba lepiej jak
> >> już na wstępie system zrezygnuje ze sprawdzania dalszych członów.
> > W sumie racja, jeśli pola w danym silniku są zorganizowane jako
> > tabele kolumnowe, to nie musi dociągać pozostałych danych. Można
> > obliczenia wykonywane w klauzuli where przyspieszyć ze 1.5 raza.
> > A to w niektórych przypadkach może dać zysku z 10% na całym
> > zapytaniu. Pytanie czy warto się bić o te 10%?
> > (...)
> 
> Patrz szerzej.
> Przy jednym kliencie może to być 10%.
> Jeśli jest to baza danych "firmowa" (czyli obsługująca magazyn, handel, 
> kadry, itd.) to klientów (równoczesnych) może być kilkudziesięciu, a 
> zapytać setki czy tysiące.
> Jeśli jest to sklep internetowy, to klientów mogą być setki.
> Wtedy każde 10% robi radykalną różnicę. A jeśli się "umie" robić selecty 
> na widokach (w MSSQL), to chyba też jest duży plus.
Patrzę szerzej i widzę... replikację. Wiem, zakup i utrzymanie
nowej maszyny kosztuje, ale praca specjalistów która przyspieszy o 10%
też jest droga.


> Ja czasami widzę coś w rodzaju:
> select (...) where (...) and (...) and 1=1
> 
> Co ciekawe, bez warunku "and 1=1" odpowiedź idzie dłużej. Dziwne, gdyż 
> teoretycznie każdy nowy warunek powinien przedłużyć odpowiedź. Ważne też 
> jest, w którym miejscu siedzi owo 1=1.
Właśnie o czymś bardzo podobnym piszę.


> Ale tu już trzeba dogłębnie znać silnik.
Właśnie często próbuję różne dyskusje sprowadzić na 
taki tor. Ja bym chciał umieć przewidywać czasy
zapytań przy różnych konfiguracjach bazy i na różnym
sprzęcie.


Pozdrawiam

> 
> 
> -- 
> Pozdrawiam.
> 
> Adam
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194330
Author: wloochacz
Date: Sat, 14 Mar 2015 22:37
23 lines
2566 bytes
W dniu 2015-03-14 o 06:13, artiun pisze:
> 1. null nigdy nie był traktowany jako wartość pusta stringu (głupota,
> chociaż bywało - to zależało od bazy)
Zaraz, chwila... Twierdzisz, że głupotą jest to, że null nie był 
traktowany jako pusty string?
Jeśli naprawdę tak uważasz, to ja nie mam nic więcej do powiedzenia - 
szkoda prądu i mojego czasu.

> 2. zasady matematyczne (+-)(*/) i zbiory
Chodzi o to jak traktowany jest null? OIDP, to jest to określone w 
standardzie ANSI. Generalnie wszystkie operacje arytmetyczne z wartością 
null, dadzą nulla na wyjściu.
Ale agregaty (i sortowanie też) działają inaczej - i tu w wielu 
silnikach można tym sterować jak ma to działać (np. order by null 
first|last).

> 3. jeśli baza jest zła (to dlaczego używa ją tyle firm)
Chodzi Ci o MySQL?
To, że coś jest fatalne nie oznacza, że nie jest popularne.
Ale to naprawdę temat nie tę grupę/dyskusję...

-- 
wloochacz
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194331
Author: nkab
Date: Wed, 18 Mar 2015 12:02
48 lines
3262 bytes
W dniu piątek, 13 marca 2015 01:49:18 UTC+1 użytkownik IDKrzych napisał:

> ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana 
> składnia nie działa -> czyli prawidłowo ..
> Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?
> 

Nie działa prawidłowo?

Załóż sobie dwa pola jedno p1 char, drugie p2 decimal.
Na jakiś pojedynczych rekordach daj jakieś wartości, na tekstowych również
jakąś jedną spację a na numeryku wpisz zero na pozostałych rekordach
zaś same NULLe.

I teraz:

select * from t4 where p1 IS NULL or p2 IS NULL;
select * from t4 where p1='' or p2=0.00;


select * from t4 where p1 IS NOT NULL or p2 IS NOT NULL;
select * from t4 where p1<>'' or p2<>'';


Wyniki będą prawidłowe, zgodne z oczekiwaniami,
czasy z IS NOT NULL odrobinkę dłuższe od <>''.


Pokaż mi przykład, który wykazuje nieprawidłowy wynik.



Minie zawsze interesowały rzeczywiste wyniki
nawet jeśli standardy są inne.

Zgodnie ze standardem warunek powinien wyglądać tak:
select * from t4 where p1<>'' or p1 IS NOT NULL or p2<>0.00 or p2 IS NOT NULL;



Oczywiście różne bazy mogą różnie działać
ale w SQLite 3 moja składnia też daje mi wynik prawidłowy
po prostu przy przesiadce i tak trzeba wszystko sprawdzać.

Zacząłem przygodę z MySQL i chyba już nie zmienię bazy
stąd nie martwię się innymi systemami (chociaż korci mnie PG).

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194332
Author: IDKrzych
Date: Sat, 21 Mar 2015 02:00
56 lines
3574 bytes
W dniu 2015-03-18 o 13:02, nkab@toya.net.pl pisze:
> W dniu piątek, 13 marca 2015 01:49:18 UTC+1 użytkownik IDKrzych napisał:
>
>> ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana
>> składnia nie działa -> czyli prawidłowo ..
>> Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?
>>
>
> Nie działa prawidłowo?

... Mam chwilkę to jednak odpiszę/dopytam .. a co mi ..

> select * from t4 where p1 IS NULL or p2 IS NULL;
> select * from t4 where p1='' or p2=0.00;
>
> select * from t4 where p1 IS NOT NULL or p2 IS NOT NULL;
> select * from t4 where p1<>'' or p2<>'';
>
> Wyniki będą prawidłowe, zgodne z oczekiwaniami,
> czasy z IS NOT NULL odrobinkę dłuższe od <>''.

ale jakie wyniki???
co chciałeś odpytać powyższymi zapytaniami i co spodziewałeś się dostać 
w wyniku??
Prawie każde (poprawne) zapytanie da się wykonać ... ale to nie dowodzi, 
że jest ono prawidłowe ze względu na intencje.

> Pokaż mi przykład, który wykazuje nieprawidłowy wynik.

Gdzieś tam wcześniej napisałeś "... p1<>NULL ..."
Ten warunek jest sam w sobie nieprawidłowy, bo jego wynikiem ZAWSZE 
będzie NULL ... bez znaczenia jaka jest wartość p1.


> Minie zawsze interesowały rzeczywiste wyniki
> nawet jeśli standardy są inne.
>
> Zgodnie ze standardem warunek powinien wyglądać tak:
> select * from t4 where p1<>'' or p1 IS NOT NULL or p2<>0.00 or p2 IS NOT NULL;

Co? Jakim standardem? ..nie rozumiem
Piszesz jakieś zapytania, ale ja nie mam pojęcia co one mają dać za 
wynik ... bo jakiś zawsze dadzą..

... ale rozmawialiśmy o tym, że nie porównuje się Nulli wprost z 
jakąkolwiek wartością, bo to jest błąd.


-- 
IDKrzych

"Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
- ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
wielowymiarowym,
w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
(S. Lem 1999)
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194333
Author: nkab
Date: Mon, 23 Mar 2015 07:38
70 lines
4411 bytes
W dniu sobota, 21 marca 2015 03:00:25 UTC+1 użytkownik IDKrzych napisał:
> W dniu 2015-03-18 o 13:02, nkab@toya.net.pl pisze:
> > W dniu piątek, 13 marca 2015 01:49:18 UTC+1 użytkownik IDKrzych napisał:
> >
> >> ale czegoś nie rozumiem .. sprawdziłem, u mnie w MySQL taka gówniana
> >> składnia nie działa -> czyli prawidłowo ..
> >> Nie wiem skąd wymysł, że można tak gówniano nulle porównywać?
> >>
> >
> > Nie działa prawidłowo?
> 
> ... Mam chwilkę to jednak odpiszę/dopytam .. a co mi ..
> 
> > select * from t4 where p1 IS NULL or p2 IS NULL;
> > select * from t4 where p1='' or p2=0.00;
> >
> > select * from t4 where p1 IS NOT NULL or p2 IS NOT NULL;
> > select * from t4 where p1<>'' or p2<>'';
> >
> > Wyniki będą prawidłowe, zgodne z oczekiwaniami,
> > czasy z IS NOT NULL odrobinkę dłuższe od <>''.
> 
> ale jakie wyniki???
> co chciałeś odpytać powyższymi zapytaniami i co spodziewałeś się dostać 
> w wyniku??
> Prawie każde (poprawne) zapytanie da się wykonać ... ale to nie dowodzi, 
> że jest ono prawidłowe ze względu na intencje.
> 
> > Pokaż mi przykład, który wykazuje nieprawidłowy wynik.
> 
> Gdzieś tam wcześniej napisałeś "... p1<>NULL ..."
> Ten warunek jest sam w sobie nieprawidłowy, bo jego wynikiem ZAWSZE 
> będzie NULL ... bez znaczenia jaka jest wartość p1.
> 
> 
> > Minie zawsze interesowały rzeczywiste wyniki
> > nawet jeśli standardy są inne.
> >
> > Zgodnie ze standardem warunek powinien wyglądać tak:
> > select * from t4 where p1<>'' or p1 IS NOT NULL or p2<>0.00 or p2 IS NOT NULL;
> 
> Co? Jakim standardem? ..nie rozumiem
> Piszesz jakieś zapytania, ale ja nie mam pojęcia co one mają dać za 
> wynik ... bo jakiś zawsze dadzą..
> 
> ... ale rozmawialiśmy o tym, że nie porównuje się Nulli wprost z 
> jakąkolwiek wartością, bo to jest błąd.
> 
> 
> -- 
> IDKrzych
> 
> "Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
> - ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
> wielowymiarowym,
> w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
> (S. Lem 1999)

Oczekiwany wynik to - daj mi wszystko co nieużyteczne, a więc
pomiń NULLe i puste lub zerowe pola.


W ogóle to sprawdzam wyniki warunków w selectach:
SELECT p1<>'', p2<>'' FROM t1;

Dzięki za chęć wykazania błędu w moim warunku bo to może mi pokazać,
że moje podejście do programowania jest błędne (nie ważne standardy,
ważny jest prawidłowy wynik).

Andrzej.
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194334
Author: IDKrzych
Date: Mon, 23 Mar 2015 14:42
58 lines
3916 bytes
>>> select * from t4 where p1 IS NULL or p2 IS NULL;
>>> select * from t4 where p1='' or p2=0.00;
>>>
>>> select * from t4 where p1 IS NOT NULL or p2 IS NOT NULL;
>>> select * from t4 where p1<>'' or p2<>'';
>>>
>>> Wyniki będą prawidłowe, zgodne z oczekiwaniami,
>>> czasy z IS NOT NULL odrobinkę dłuższe od <>''.

Ale to nie są pary symetrycznych logicznie zapytań.
Pierwsze zwraca TYLKO nulle
Drugie zwraca wartości "" oraz 0
Trzecie zwraca WSZYSTKIE wartości
Czwarte zwraca wartości różne od pustego ciągu.

>>> Minie zawsze interesowały rzeczywiste wyniki
>>> nawet jeśli standardy są inne.
>>>
>>> Zgodnie ze standardem warunek powinien wyglądać tak:
>>> select * from t4 where p1<>'' or p1 IS NOT NULL or p2<>0.00 or p2 IS NOT NULL;

Niekoniecznie ...
Wybieranie wartości różnych od '' lub 0 nie zwróci wartości null (null 
nie jest różne od '' -> taka jest logika null-i).
Więc wystarczy tylko: select * from t4 where p1<>'' or p2<>0;


> Oczekiwany wynik to - daj mi wszystko co nieużyteczne, a więc
> pomiń NULLe i puste lub zerowe pola.

Chaotycznie piszesz :( Nawet powyższe zdanie jest przecież sprzeczne?
Chciałeś w końcu w wyniku mieć nieużyteczne dane czy jednak pomijać?
Domyślam się co chciałeś napisać, ale ... pisz wolniej ;)

> W ogóle to sprawdzam wyniki warunków w selectach:
> SELECT p1<>'', p2<>'' FROM t1;
>
> Dzięki za chęć wykazania błędu w moim warunku bo to może mi pokazać,
> że moje podejście do programowania jest błędne (nie ważne standardy,
> ważny jest prawidłowy wynik).

I bardzo dobrze, że testujesz.
Musisz jednak pamiętać, że NULL nie jest wartością i zachowuje się 
zupełni inaczej.
Null to brak wartości, który o cokolwiek go zapytasz odpowie "brak 
wartości" :)
Dlatego gdy potrzebujesz wyszczególnić Null-e musisz używać "is null" i 
nigdy nie wolno porównywać NULLi wprost z innymi wartościami.
NIGDY, NIGDZIE.

-- 
IDKrzych

"Jakkolwiek będzie - będzie inaczej, aniżeli sobie wyobrażamy
- ponieważ między Dobrem a Złem znajdujemy się w życiu i w świecie
wielowymiarowym,
w którym dokumentnie pomieszane jest Przypadkowe z Nieuchronnym."
(S. Lem 1999)
Re: PostgreSQL - jak zbudować optymalne zapytanie?
#194335
Author: nkab
Date: Tue, 24 Mar 2015 06:53
59 lines
4075 bytes
W dniu poniedziałek, 23 marca 2015 15:42:04 UTC+1 użytkownik IDKrzych napisał:
> >>> select * from t4 where p1 IS NULL or p2 IS NULL;
> >>> select * from t4 where p1='' or p2=0.00;
> >>>
> >>> select * from t4 where p1 IS NOT NULL or p2 IS NOT NULL;
> >>> select * from t4 where p1<>'' or p2<>'';
> >>>
> >>> Wyniki będą prawidłowe, zgodne z oczekiwaniami,
> >>> czasy z IS NOT NULL odrobinkę dłuższe od <>''.
> 
> Ale to nie są pary symetrycznych logicznie zapytań.
> Pierwsze zwraca TYLKO nulle
> Drugie zwraca wartości "" oraz 0
> Trzecie zwraca WSZYSTKIE wartości
> Czwarte zwraca wartości różne od pustego ciągu.
> 

W tej pierwszej parze zapytań chodziło mi tylko
o to, że NULLe to co innego niż pusty ciąg.

W tej drugiej parze, że pomijane są albo tylko NULLe
albo uniwersalnie i NULLe i puste ciągi, że <>'' w MySQL
nie wymaga sprawdzania obu - i NULLa i pustego ciągu.


> 
> > Oczekiwany wynik to - daj mi wszystko co nieużyteczne, a więc
> > pomiń NULLe i puste lub zerowe pola.
> 
> Chaotycznie piszesz :( Nawet powyższe zdanie jest przecież sprzeczne?
> Chciałeś w końcu w wyniku mieć nieużyteczne dane czy jednak pomijać?
> Domyślam się co chciałeś napisać, ale ... pisz wolniej ;)
> 


O kurcze, rzeczywiście mam brzydki zwyczaj nie czytania
tego co napisałem a piszę wolniej niż myślę, w ogóle
ostatnio łapią mnie kobitki na takich wpadkach ale to
wynik lenistwa bo w pracy nudy a wiek nie zachęca już
do robienia rzeczy nowych. Poprawię się.


> Null to brak wartości, który o cokolwiek go zapytasz odpowie "brak 
> wartości" :)
> Dlatego gdy potrzebujesz wyszczególnić Null-e musisz używać "is null" i 
> nigdy nie wolno porównywać NULLi wprost z innymi wartościami.
> NIGDY, NIGDZIE.
> 

No tyle to wiem i dodam, że nie ma typu (text, integer...).

Ten dyskutowany warunek to dla Marka, który pisze wyszukiwarkę
i ma bardzo dużo NULLi, które chciał wyeliminować w konstruowaniu
złożonego zapytania ale on używa PG, który tej składni może nie łyknąć.


Dzięki za dyskusję.

Andrzej.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads