![]() |
![]() |
![]()
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!
|
|
|
![]() |
![]()
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 :/
|
|
|
![]()
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
![]() -------------------- audaces fortuna iuvat!
|
|
|
![]()
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..."
|
|
|
![]()
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.
|
|
|
![]()
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..."
|
|
|
![]()
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!
|
|
|
![]()
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 :/
|
|
|
![]()
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...
![]() -------------------- audaces fortuna iuvat!
|
|
|
![]()
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 ![]() [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 |
|
|
![]()
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 ![]() -------------------- Brak czasu :/
|
|
|
![]() ![]() |
![]() |
Aktualny czas: 20.08.2025 - 09:10 |