![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 215 Pomógł: 44 Dołączył: 31.07.2011 Skąd: wrocław Ostrzeżenie: (0%) ![]() ![]() |
Witam.
Mam taką funkcję:
Nie będę tłumaczył wszystkiego, osoby znające się zrozumieją na pewno (po nazwach funkcji wiadomo o co chodzi). Chodzi o to, że w jednej tabeli mam miejscowości wraz ze współrzędnymi geograficznymi, a w drugiej odległości między miejscowościami. W ten sposób jak ja to rozwiązałem to strasznie wolno chodzi (obecnie w bazie jest ok 1000 miejscowości). Co prawda obliczam tylko raz, ew. aktualizacja w przyszłości po dodaniu nowych miejscowości, ale tak z ciekawości chciałbym was zapytać, czy widzicie jakieś lepsze rozwiązanie? Tak jak mam w przykładzie dla LIMIT 3000 u mnie na laptopie funkcja wykonuje się ponad 15 sekund. Kiedyś to zrobiłem bardziej w php, przeleciałem całą tabelę w pętlach, ale dzięki temu sposobowi łatwiej mi jest dodawać nowe miejscowości. |
|
|
![]()
Post
#2
|
|
Grupa: Przyjaciele php.pl Postów: 1 224 Pomógł: 40 Dołączył: 6.07.2004 Skąd: Wuppertal Ostrzeżenie: (0%) ![]() ![]() |
jak wyglada fu.kcja distance from coords. Nie moglbys jej na mysql przerzucic?
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 215 Pomógł: 44 Dołączył: 31.07.2011 Skąd: wrocław Ostrzeżenie: (0%) ![]() ![]() |
Właśnie jest tam trochę obliczeń:
Bałem się nawet myśleć o tym, żeby obliczenia robić w mysql (IMG:style_emoticons/default/smile.gif) Nawet nie chciałem próbować zrobić tego tylko w mysql, a tu proszę jak szybko poszło: całą bazę (niecałe 500tys) wygenerowane w niecałe 20 sekund:
Ma ktoś może teraz sugestie, jak zoptymalizować to zapytanie? |
|
|
![]()
Post
#4
|
|
Grupa: Przyjaciele php.pl Postów: 1 224 Pomógł: 40 Dołączył: 6.07.2004 Skąd: Wuppertal Ostrzeżenie: (0%) ![]() ![]() |
Kod explain SELECT i1, i2, DEGREES(acos(sin(x1) * sin(x2) + cos(x1) * cos(x2) * cos(y1-y2)))*111189.57696 FROM (SELECT id as i1, RADIANS(latitude) as x1, RADIANS(longitude) as y1 FROM %1$s) as t1, (SELECT id as i2, RADIANS(latitude) as x2, RADIANS(longitude) as y2 FROM %1$s) as t2 WHERE i1<i2 AND i1 NOT IN (SELECT id1 from %2$s WHERE id1 = i1 AND id2 = i2 wykonaj i wklej wynik |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 215 Pomógł: 44 Dołączył: 31.07.2011 Skąd: wrocław Ostrzeżenie: (0%) ![]() ![]() |
Dzięki, już daję wynik:
|
|
|
![]()
Post
#6
|
|
Grupa: Przyjaciele php.pl Postów: 1 224 Pomógł: 40 Dołączył: 6.07.2004 Skąd: Wuppertal Ostrzeżenie: (0%) ![]() ![]() |
bez danych nie potrafię Ci pomóc. nie wiem czy nie jesteś w stanie zamienić tych podzapytań na zwykłego joina, i druga sprawa jak robisz RADIANS(latitude) as x1 to za każdym razem mysql musi to policzyć, być może wyda się lepsze żeby te dane trzymać w dodatkowych kolumnach żeby nie trzeba było ich liczyć za każdym razem.
|
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 215 Pomógł: 44 Dołączył: 31.07.2011 Skąd: wrocław Ostrzeżenie: (0%) ![]() ![]() |
Dzięki. Odnośnie radianów, to wolę je liczyć, bo wykorzystuję je tylko i wyłącznie przy obliczaniu właśnie tych odległości, a że nieczęsto będzie to liczone, to wolę stracić na czasie. W sumie to już zostawiam tak jak mam, teraz nowy problem mi wyskoczył, może rano po przebudzeniu mnie olśni.
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 262 Pomógł: 39 Dołączył: 12.04.2004 Ostrzeżenie: (0%) ![]() ![]() |
Kod WHERE i1<i2 AND i1 NOT IN (SELECT id1 from %2$s WHERE id1 = i1 AND id2 = i2) To nie wygląda najlepiej, a przy Twojej strukturze zapytania z indeksami cięzko. Polecam pozbyć się NOT IN albo zmienić zapytanie tak, żeby nie generowało tymczasowych danych, tylko operowało na istniejących tabelach. i1<i2 też lekkie nie jest. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 14.09.2025 - 23:24 |