Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> query z kilku tabel - opytmalizacja
zombie
post
Post #1





Grupa: Zarejestrowani
Postów: 296
Pomógł: 0
Dołączył: 9.05.2002
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Witam! Mam takie zapytanie do MySQL'a:
[sql:1:852d7fa5ee]SELECT tabela.id, tabela.imie, tabela.plec, tabela.ur, (YEAR(CURDATE())-YEAR(tabela.ur)) - (RIGHT(CURDATE(),5)<RIGHT(tabela.ur,5)) AS wiek, tabela.city, tabela.icq, tabela.gg, tabela.tlen, tabela.wpk, tabela.aqq, DATE_FORMAT(tabela.data,'%Y-%m-%d'), tabela.zdjecie, tabela.banned, ((tabela_pkt.humor*3) + tabela_pkt.sciana) AS punkty FROM tabela, tabela_pkt WHERE tabela.imie LIKE '".$_POST['l']."%' ORDER BY tabela.".$_GET['ord']." ".$aod.", tabela.imie ASC LIMIT ".(($_GET['pg'])*$HM).", ".$HM[/sql:1:852d7fa5ee]

... problem polega na tym, że takie zapytanie wykonuje się wręcz do kilkunastu sekund. Jak można zoptymalizaowć taki kod? Zalezy mi na tym, żeby pobierać dane z wielu tabel jednym zapytaniu, bo to upraszcza sortowanie... Czy jest to w ogóle możliwe, czy konieczna jest opcja, tak, jak na forum, np. "pokaż 10 najlepszych" i wtedy pobrać dane z tabela_pkt a w drugin query z tabela..?


--------------------
audaces fortuna iuvat!
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 10)
FiDO
post
Post #2





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


Przede wszystkim zmien [sql:1:dd3fb74fae]WHERE tabela.imie LIKE '".$_POST['l']."%'[/sql:1:dd3fb74fae]
na
[sql:1:dd3fb74fae]WHERE INSTR(tabela.imie, '".$_POST['l']."') = 1[/sql:1:dd3fb74fae]
Po drugie zaloz indexy na pola uzywane w ORDER BY


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post
zombie
post
Post #3





Grupa: Zarejestrowani
Postów: 296
Pomógł: 0
Dołączył: 9.05.2002
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Dzięki FiDO, ale to mojego problemu nie rozwiązuje... a wręcz przeciwenie,... działa jeszcze wolniej sad.gif


--------------------
audaces fortuna iuvat!
Go to the top of the page
+Quote Post
DeyV
post
Post #4





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Zastanwaie mnie w tym zapytaniu jedno. W jaki sposób te tabele są ze sobą 'łączone' Nie ma żadnego warunku 'łaczącego' je ani w WHERE, ani żadnego JOIN
Może to powoduje nieoptymalne działanie, bo znacznie zwiększa ilość wyników?


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
Dravo
post
Post #5





Grupa: Zarejestrowani
Postów: 207
Pomógł: 0
Dołączył: 7.09.2003

Ostrzeżenie: (0%)
-----


tabele się łączą przez przecinek (Full Join) [ w klauzuli FROM ]
Według mnie jednak powinno w klauzuli WHERE związać sie obie tabele warunkami np. tab1.id = tab2.id, po prostu musza mieć jakieś wspólne pola, np. id.
Nie jestem ekspertem, ale na chlopski rozum, jeśli nie ma warunków łącznia się tabel, to łączą się całe, co zwalania zapytanie. Jeśli natomiast określimy fragmemnty tabel, które mają się łączyć cay proces może się przyspieszyć.
Jednak trzebabyłoby to sprawdzić.

UPDATE 1
Stosuj aliasy do nazwy tabel i pól [w tym przypadku zwłaszcza do tabel], np. tabela_pkt as pkt.


--------------------
Oooo, cia is on the phone... Ok, I got it. Shit I lost it.
Go to the top of the page
+Quote Post
DeyV
post
Post #6





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




tak się zastanawiam, czy ja nie napisałem tego samego, co Ty, Dravo?

ps. aliasy nie mają znaczenia dla prędkości.


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
zombie
post
Post #7





Grupa: Zarejestrowani
Postów: 296
Pomógł: 0
Dołączył: 9.05.2002
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Dzieki Panowie, rzeczywiscie pomoglo [sql:1:21324c5209]WHERE tabela.kolumna = tabela_pkt.kolumna[/sql:1:21324c5209]


--------------------
audaces fortuna iuvat!
Go to the top of the page
+Quote Post
FiDO
post
Post #8





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


No to teraz porownaj sobie wydajnosc z tym co podalem i bez tego.
Tylko doloz jeszcze indeksy na pola laczace dwie tabele (te w powyzszym WHERE)


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post
zombie
post
Post #9





Grupa: Zarejestrowani
Postów: 296
Pomógł: 0
Dołączył: 9.05.2002
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Spox. Gania jak wariat teraz... smile.gif acz różnica pomiędzy LIKE a INSTR zdaje się być niewielka ...


--------------------
audaces fortuna iuvat!
Go to the top of the page
+Quote Post
Indeo
post
Post #10





Grupa: Zarejestrowani
Postów: 295
Pomógł: 7
Dołączył: 26.03.2004
Skąd: Opole

Ostrzeżenie: (0%)
-----


Tu już nawet nie chodzi o optymalizację ale o dosłowne mordowanie bazy danych.

Po pierwsze. Konstrukcja łączenia tabel bez użycia instrukcji INNER JOIN, LEFT JOIN itd. nadaje się do używania przez przedszkolaków. Jak ktoś nie wierzy to niech sobie zrobi najprostszą kwerendę w MSAccess i zobaczy, że nawet głupi Acces od razu tworzy instrukcji INNER.

Łączenie tabel winno się odbywac następująco:
[sql:1:d05366fede]
SELECT tabela1.pole2,tabela2.pole2 FROM tabela1 INNER JOIN tabela2 ON tabela1.pole1=tabela2.pole1 where tabela1.pole4 LIKE '%tra la la%'
[/sql:1:d05366fede]
Po drugie indeksy, indeksy i jeszcze raz indeksy. Na kazdym kroku gdzie łączy się tabele należy używac indeksów jako kluczy łączących tabele. W przeciwnym razie zapytanie do bazy może być tak bolesne że obciąży procesor w 100% i zawiesi komputer.

Jeśli ktoś sobie nie radzi lub wręcz zapisanie tego co sie chce zrobić w jednym zapytaniu jest niemożliwe to nikomu korona z głowy nie spadnie jak rozłoży zapytanie na kilka podzapytań, których wyniki załaduje do nowych tabel (temporary table), uworzy w nich indeksy i wykona ostateczne zapytanie.
Przestudiowanie 3 prostych zapytań jest 100 razy szybsze niż ślęczenie 6 godzin nad zapytaniem w którym użyto 4 instrukcje IF jedna w drugiej.

A oto przykładowe zapytanie do bazy na której pracuję i niech ktoś spróbuje zapisać takie zapytanie bez INNERÓW smile.gif:

[sql:1:d05366fede]
#zrzuty na pktach zlewnych
drop table polacz15;
create temporary table polacz15 select distinct nr_polacz from polaczenia where polaczenia.adres like '%cieki%zlewny%' or polaczenia.adres like '%cieki%wykaz%';

alter table polacz15 add primary key(nr_polacz);

#Zużycia na punkcie zlewnym
select count(distinct symb_polacz),rach.taryfa,platnik.symb_plat,platnik.nazwa,polaczenia.symb_polacz,
olaczenia.adres,
sum(if(rach.taryfa like '_R' or rach.taryfa like '_W',rach.zuzycie-ifnull(rach_1.zuzycie,0),0)) as woda,
sum(if(rach.taryfa like '_R' or rach.taryfa like '_S',rach.zuzycie-ifnull(rach_1.zuzycie,0),0)) as scieki
from polacz15
left join rach on polacz15.nr_polacz=rach.nr_polacz
left join rach as rach_1 on rach.rach_rekl_nr=rach_1.nr_rach and rach.nr_plat=rach_1.nr_plat and rach.nr_polacz=rach_1.nr_polacz and
rach.nr_lewego=rach_1.nr_lewego and rach.taryfa=rach_1.taryfa and rach.cena_wody=rach_1.cena_wody and rach.cena_sciekow=rach_1.cena_sciekow
inner join polaczenia on rach.nr_polacz=polaczenia.nr_polacz
inner join platnik on rach.nr_plat=platnik.nr_plat
where
rach.rok_spr=2004 and rach.mies_spr=1
group by taryfa

order by symb_plat

[/sql:1:d05366fede]

Pozdrawiam
Go to the top of the page
+Quote Post
FiDO
post
Post #11





Grupa: Przyjaciele php.pl
Postów: 1 717
Pomógł: 0
Dołączył: 12.06.2002
Skąd: Wolsztyn..... Studia: Zielona Góra

Ostrzeżenie: (0%)
-----


A mozesz podac konkrety? I jeszcze porownanie z i bez indexow?

Nie mialem do tej pory mozliwosci sprawdzenia tego na wiekszej ilosci danych, a chetnie bym sie dowiedzial na ile teoria przeklada sie na praktyke smile.gif


--------------------
Brak czasu :/
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 09:10