ďťż
 
[MySQL] LEFT JOIN - strasznie wolny ďťż
 
[MySQL] LEFT JOIN - strasznie wolny
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

[MySQL] LEFT JOIN - strasznie wolny



Yarro - 01-08-2006 01:51
[MySQL] LEFT JOIN - strasznie wolny
  Witam,

W wielkim uproszczeniu struktura danych jest nastepujaca (2 tabele):

transport
=========
nr_transportu int (primary key, not null)
opis_transportu varchar(30)
data_wyjazdu datetime
nr_zamowienia varchar(10) (null mozliwy)

zamowienia
==========
nr_zamowienia varchar(10) (primary key, not null)
opis_zamowienia varchar(30)
nr_transportu int

--------------------------------------------------
w bazie MySQL 4.1.19 (win) jest:
zamowienia: 1400 rekordow
transporty: 800 rekordow

Dopiero jak znany jest nr_transportu dla konkretnego zamowienia updotowana
jest tabela zamowienia gdzie w pole nr_transportu wpisujemy numer
transportu. Sa wiec zamowienia, ktrore w polu nr_transportu maja NULL.

Chce wybrac wszystkie nr transportu (ktore wyjechaly) wraz z infor z tabeli
zamowienia ale konicznie
musza sie na liscie pojawic rowniez transporty, ktore nie maja przypisanych
numerow transportu w polu
nr_transportu:

select
tra.nr_transportu,
zam.nr_zamowienia
from
(transporty tra LEFT JOIN zamowienia zam on
tra.nr_transportu=zam.nr_transportu)
WHERE tra.data_wyjazdu is not null
order by tra.nr_transportu desc;

w rezultacie otrzymuje okolo 290 rekordow ale przetwarzanie tego zapytania
trwa okolo 6-7 sekund.

Te dwie tabelki wrzucilem do MS ACCESS. Z reki wpisalem dokladnie to samo
zamowienia i na tym samym kompie czas wykonywania jest bardzo krotki:
rezultaty pojawiaja sie natychmiast po odpaleniu kwerendy !!!

Dlaczego LEFT JOIN jest w MySQL taki wolny (jak na chwile zamienilem go na
INNER JOIN zapytanie wykonalo sie w Mysqlu w 0,01 sec). Skoro Access
poradzil sobie z tym zapytaniem w ułamek sekundy to co zrobic aby tak samo
szybko działało ono w MYSQL.

Pozdrawiam
Yarro





Artur Gancarz - 02-08-2006 00:06

  Użytkownik Yarro napisał:
> Witam,
>
> W wielkim uproszczeniu struktura danych jest nastepujaca (2 tabele):
>
> transport
> =========
> nr_transportu int (primary key, not null)
> opis_transportu varchar(30)
> data_wyjazdu datetime
> nr_zamowienia varchar(10) (null mozliwy)
>
> zamowienia
> ==========
> nr_zamowienia varchar(10) (primary key, not null)
> opis_zamowienia varchar(30)
> nr_transportu int
>
> --------------------------------------------------
> w bazie MySQL 4.1.19 (win) jest:
> zamowienia: 1400 rekordow
> transporty: 800 rekordow
>
> Dopiero jak znany jest nr_transportu dla konkretnego zamowienia updotowana
> jest tabela zamowienia gdzie w pole nr_transportu wpisujemy numer
> transportu. Sa wiec zamowienia, ktrore w polu nr_transportu maja NULL.
>
> Chce wybrac wszystkie nr transportu (ktore wyjechaly) wraz z infor z tabeli
> zamowienia ale konicznie
> musza sie na liscie pojawic rowniez transporty, ktore nie maja przypisanych
> numerow transportu w polu
> nr_transportu:
>
> select
> tra.nr_transportu,
> zam.nr_zamowienia
> from
> (transporty tra LEFT JOIN zamowienia zam on
> tra.nr_transportu=zam.nr_transportu)
> WHERE tra.data_wyjazdu is not null
> order by tra.nr_transportu desc;
>
> w rezultacie otrzymuje okolo 290 rekordow ale przetwarzanie tego zapytania
> trwa okolo 6-7 sekund.
>
> Te dwie tabelki wrzucilem do MS ACCESS. Z reki wpisalem dokladnie to samo
> zamowienia i na tym samym kompie czas wykonywania jest bardzo krotki:
> rezultaty pojawiaja sie natychmiast po odpaleniu kwerendy !!!
>
> Dlaczego LEFT JOIN jest w MySQL taki wolny (jak na chwile zamienilem go na
> INNER JOIN zapytanie wykonalo sie w Mysqlu w 0,01 sec). Skoro Access
> poradzil sobie z tym zapytaniem w ułamek sekundy to co zrobic aby tak samo
> szybko działało ono w MYSQL.
>
> Pozdrawiam
> Yarro
>
>
>
>
Witam,
wg mojej wiedzy Twój indeks po którym chcesz przypisywać do siebie
wyniki z obu tabel (tj. nr_zamowienia) jest po prostu nietrafiony.
Uznałeś, że będzie to varchar(). Ten typ pola jest "straszelnie" długo
przetwarzany i prawdopodobnie stąd wynika prędkość przetwarzania.
Proponuje zastanowić się nad zmianą typu choćby na char i zdaje się, że
będzie o wieeeeele szybciej....

pozdrawiam
Artur




Artur Muszynski - 02-08-2006 00:06

  > wg mojej wiedzy Twój indeks po którym chcesz przypisywać do siebie
> wyniki z obu tabel (tj. nr_zamowienia) jest po prostu nietrafiony.
> Uznałeś, że będzie to varchar(). Ten typ pola jest "straszelnie" długo
> przetwarzany i prawdopodobnie stąd wynika prędkość przetwarzania.
> Proponuje zastanowić się nad zmianą typu choćby na char i zdaje się,
> że będzie o wieeeeele szybciej....

Pierwsze słyszę. Nullowalność to owszem, ma jakiś wpływ na wydajność.

artur




Yarro - 02-08-2006 00:48

 
Użytkownik "Artur Gancarz" <einstein@agh.edu.pl> napisał w wiadomości
news:eal712$pmb$1@news.agh.edu.pl...
> Użytkownik Yarro napisał:
>> Witam,
>>
>> W wielkim uproszczeniu struktura danych jest nastepujaca (2 tabele):
>>
>> transport
>> =========
>> nr_transportu int (primary key, not null)
>> opis_transportu varchar(30)
>> data_wyjazdu datetime
>> nr_zamowienia varchar(10) (null mozliwy)
>>
>> zamowienia
>> ==========
>> nr_zamowienia varchar(10) (primary key, not null)
>> opis_zamowienia varchar(30)
>> nr_transportu int
>>
>> --------------------------------------------------
>> w bazie MySQL 4.1.19 (win) jest:
>> zamowienia: 1400 rekordow
>> transporty: 800 rekordow
>>
>> Dopiero jak znany jest nr_transportu dla konkretnego zamowienia
>> updotowana
>> jest tabela zamowienia gdzie w pole nr_transportu wpisujemy numer
>> transportu. Sa wiec zamowienia, ktrore w polu nr_transportu maja NULL.
>>
>> Chce wybrac wszystkie nr transportu (ktore wyjechaly) wraz z infor z
>> tabeli
>> zamowienia ale konicznie
>> musza sie na liscie pojawic rowniez transporty, ktore nie maja
>> przypisanych
>> numerow transportu w polu
>> nr_transportu:
>>
>> select
>> tra.nr_transportu,
>> zam.nr_zamowienia
>> from
>> (transporty tra LEFT JOIN zamowienia zam on
>> tra.nr_transportu=zam.nr_transportu)
>> WHERE tra.data_wyjazdu is not null
>> order by tra.nr_transportu desc;
>>
>> w rezultacie otrzymuje okolo 290 rekordow ale przetwarzanie tego
>> zapytania
>> trwa okolo 6-7 sekund.
>>
>> Te dwie tabelki wrzucilem do MS ACCESS. Z reki wpisalem dokladnie to samo
>> zamowienia i na tym samym kompie czas wykonywania jest bardzo krotki:
>> rezultaty pojawiaja sie natychmiast po odpaleniu kwerendy !!!
>>
>> Dlaczego LEFT JOIN jest w MySQL taki wolny (jak na chwile zamienilem go
>> na
>> INNER JOIN zapytanie wykonalo sie w Mysqlu w 0,01 sec). Skoro Access
>> poradzil sobie z tym zapytaniem w ułamek sekundy to co zrobic aby tak
>> samo
>> szybko działało ono w MYSQL.
>>
>> Pozdrawiam
>> Yarro
>>
>>
>>
>>
> Witam,
> wg mojej wiedzy Twój indeks po którym chcesz przypisywać do siebie wyniki
> z obu tabel (tj. nr_zamowienia) jest po prostu nietrafiony. Uznałeś, że
> będzie to varchar(). Ten typ pola jest "straszelnie" długo przetwarzany i
> prawdopodobnie stąd wynika prędkość przetwarzania.
> Proponuje zastanowić się nad zmianą typu choćby na char i zdaje się, że
> będzie o wieeeeele szybciej....

Zauważ, że pola łącze po nr_transportu, który jest typu int.

>
> pozdrawiam
> Artur





Artur Gancarz - 02-08-2006 00:48

  Użytkownik Artur Muszynski napisał:
>> wg mojej wiedzy Twój indeks po którym chcesz przypisywać do siebie
>> wyniki z obu tabel (tj. nr_zamowienia) jest po prostu nietrafiony.
>> Uznałeś, że będzie to varchar(). Ten typ pola jest "straszelnie" długo
>> przetwarzany i prawdopodobnie stąd wynika prędkość przetwarzania.
>> Proponuje zastanowić się nad zmianą typu choćby na char i zdaje się,
>> że będzie o wieeeeele szybciej....
>
>
> Pierwsze słyszę. Nullowalność to owszem, ma jakiś wpływ na wydajność.
>
> artur
>
Hello,
a jednak...
pole typu varchar zostają zapisywane w wolnych miejscach na dysku, gdyż:
1) są zmiennej długości (pierwszy wpis jest oczywiście w miejscu reszty
danych z rekordu)
2) aktualizacja pola, a zwłaszcza jego wydłużenie powoduje, że dane do
tego pola są "wrzucane" w wolne miejsce, oznacza to ni mniej ni więcej
tylko dwukrojną "jadę" głowicą dysku aby odczytać jeden rekord, czyli w
skrajnych przypadkach ok. 2 razy dłużej czytanie

a oprócz tego:
3) zmienne znakowe są wielokrotnie dłużej przetwarzane niż liczbowe

Nie zmienia to jednak faktu, że się pomyliłem i napisałem, że łaczenie
tablej jest polem nr_zamowienia co jest błędne i nie przystaje do
rzeczywistości
Wobec treści w powyższym zdaniu niestety nie wiem, dlaczego aż tak długo
przetwarza.

Artur




Artur Gancarz - 02-08-2006 00:48

  Użytkownik Yarro napisał:
> Witam,
>
> W wielkim uproszczeniu struktura danych jest nastepujaca (2 tabele):
>
> transport
> =========
> nr_transportu int (primary key, not null)
> opis_transportu varchar(30)
> data_wyjazdu datetime
> nr_zamowienia varchar(10) (null mozliwy)
>
> zamowienia
> ==========
> nr_zamowienia varchar(10) (primary key, not null)
> opis_zamowienia varchar(30)
> nr_transportu int
>
> --------------------------------------------------
> w bazie MySQL 4.1.19 (win) jest:
> zamowienia: 1400 rekordow
> transporty: 800 rekordow
>
> Dopiero jak znany jest nr_transportu dla konkretnego zamowienia updotowana
> jest tabela zamowienia gdzie w pole nr_transportu wpisujemy numer
> transportu. Sa wiec zamowienia, ktrore w polu nr_transportu maja NULL.
>
> Chce wybrac wszystkie nr transportu (ktore wyjechaly) wraz z infor z tabeli
> zamowienia ale konicznie
> musza sie na liscie pojawic rowniez transporty, ktore nie maja przypisanych
> numerow transportu w polu
> nr_transportu:
>
> select
> tra.nr_transportu,
> zam.nr_zamowienia
> from
> (transporty tra LEFT JOIN zamowienia zam on
> tra.nr_transportu=zam.nr_transportu)
> WHERE tra.data_wyjazdu is not null
> order by tra.nr_transportu desc;
>
> w rezultacie otrzymuje okolo 290 rekordow ale przetwarzanie tego zapytania
> trwa okolo 6-7 sekund.
>
> Te dwie tabelki wrzucilem do MS ACCESS. Z reki wpisalem dokladnie to samo
> zamowienia i na tym samym kompie czas wykonywania jest bardzo krotki:
> rezultaty pojawiaja sie natychmiast po odpaleniu kwerendy !!!
>
> Dlaczego LEFT JOIN jest w MySQL taki wolny (jak na chwile zamienilem go na
> INNER JOIN zapytanie wykonalo sie w Mysqlu w 0,01 sec). Skoro Access
> poradzil sobie z tym zapytaniem w ułamek sekundy to co zrobic aby tak samo
> szybko działało ono w MYSQL.
>
> Pozdrawiam
> Yarro
>
>
>
>
Witaj,
wymyśliłem jeszcze jedną rzecz, ale nieco naciągane to jest, bo pewnie
aż tak wolno by nie robił.
Generalnie łączysz do pierwszej tabeli z transportami tabelę z
zamówieniami. Ale... dołączając do tabeli nie korzystasz z kluczy (no i
indeksów), bo do pola nr_transportu z tabeli transporty (który jest
kluczem) dołaczasz tabelę zamówienia za pomocą pola nr_transportu,
które w tej tabeli nie ma ani klucza, ani indeksu. To może być przyczyna
wolnej pracy, bo silnik bazy przegląda cała tabelę i niestety nie ma jej
nigdzie posortowanej wg tego pola więc wyszukuje na "ślepo". Może
dodanie indeksu wystarczy?

Drugim rozwiązaniem jest połączenie w drugą stronę, tj.

select
tra.nr_transportu,
zam.nr_zamowienia
from
(zamowienia zam LEFT JOIN transporty tra on
tra.nr_transportu=zam.nr_transportu)
WHERE tra.data_wyjazdu is not null
order by tra.nr_transportu desc;

Nie mam tej bazy, więc nie wiem, jak zadziała, ale chyba powinno. Zaletą
jest powyżej opisane wykorzystanie klucza głównego tabeli "transport".

ciekaw jestem, czy przyspieszyło?

Artur
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    [mysql] =?ISO-8859-2?Q?Za=E6mienie=2E=2E=2E_jak_wy=B6wietli=E6?==?ISO-8859-2?Q?=2E=2E=2E?= [mysql] =?ISO-8859-2?Q?wielko=B6=E6_bazy_a_stabilno=B6=E6=2C?==?ISO-8859-2?Q?_podzia=B3_du=BFej_bazy_a_powi=B1zania_tabel?= [MySQL] =?ISO-8859-2?Q?Wy=B6wietlenie_kolejnej_pozycji=2C_?==?ISO-8859-2?Q?jak=B1_mia=B3by_dany_rekord=2C_gdybym_czyta=B3 _?==?ISO-8859-2?Q?wg_konkretnych_kryteri=F3w=2E_Da_si=EA_=3F?= [mysql 4.0.x] przenoszenie kolum =?ISO-8859-2?Q?mi=EAdzy_bazam?==?ISO-8859-2?Q?i_cd_=2E=2E=2E_?= [MySQL] =?ISO-8859-2?Q?z=B3=B1czenie_tabeli_u=BFytkownik_i?==?ISO-8859-2?Q?_zdj=EAcia_z_wyborem_zdj=EAcia_domy=B6lnego?= [MySQL] Jak =?ISO-8859-2?Q?wpisa=E6_do_tabeli_pozycje_dl?==?ISO-8859-2?Q?a_wierszy_gdybym_te_wiersze_wybiera=B3_w_ok?== ?ISO-8859-2?Q?re=B6lonej_kolejno=B6ci_=3F?= Gdzie MySQL 4.1, a gdzie 5.0? [MySQL 4.0...4.1] zabezpieczenie przed =?ISO-8859-2?Q?jednoczesn?==?ISO-8859-2?Q?=B1_edycj=B1?= [MS SQL] "set names" (mySQL) w MS SQL [mysql 5.x] jak =?ISO-8859-2?Q?zrealizowa=E6_zapytanie=3F_cz?==?ISO-8859-2?Q?yli_podzapytanie_i_wi=EAcej_ni=BF_jeden_rz=B1? ==?ISO-8859-2?Q?d_wynik=F3w?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • autwywalczyl.opx.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com