1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function afstandTotPunt($lat1,$lng1,$lat2,$lng2) { $a1 = deg2rad($lat1); //lat 1 in radialen $a2 = deg2rad($lat2); //lat 2 (het xcoordinaat) in radialen $b1 = deg2rad($lng1); //lng 1 in radialen $b2 = deg2rad($lng2); //lng 2 (het ycoordinaat) in radialen $r = 6378.8; //de radius / straal van de aarde in kilometers return (acos(cos($a1)*cos($b1)*cos($a2)*cos($b2) + cos($a1)*sin($b1)*cos($a2)*sin($b2) + sin($a1)*sin($a2)) * $r); } ?> |
Je hebt die 300.000+ records in een database. Ik neem aan dat die dingen ook allemaal een eigen id hebben. Dan maak je een tabel aan met de velden id1, id2 en afstand (vergeet ook de indexen niet). En een scriptje om die tabel te vullen.quote:
1 2 3 4 5 6 7 8 | for(i = 1; i <= x; i++) { for(j = i + 1; j <= x; j++) { afstand = berekenAfstand(i, j) sql = 'insert into matrix(id1, id2, afstand) values (i, j, afstand)' doQuery(sql); } } |
Ja, ik had de drie weken vakantie nog maar niet genoemdquote:Op donderdag 18 juni 2009 19:45 schreef Xcalibur het volgende:
je kan ze ook ALLEMAAL uitrekenen
Dus zowel de heenweg als de terugweg zeg maar... Dan voorkom je je nadeel, en heb je feitelijk de helft aan overbodige records
Ik zou preg_replace() gebruiken.quote:Op vrijdag 19 juni 2009 18:33 schreef splendor het volgende:
Ik wil een str_ireplace gebruiken om een link ergens omheen te zetten, maar hij moet het originele woord niet veranderen qua hoofd/kleine letters. Is dat mogelijk of wordt het een eregi oid?
Bijvoorbeeld "Dit IS eEn Test" wordt niet "dit is een test" (met link eromheen dan).
Lekker goed voor de performance ookquote:
1 2 3 4 5 6 7 8 9 | function str_ireplace_case($input, $compare) { if(strcasecmp($input, $compare) === 0) return "<a href=\"whatever\">{$input}</a>"; else return $input; } ?> |
Ik ben het met je eens dat het sneller is als je geen regular expression nodig hebt. Maar van de regular expression functies presteren de preg_* functies over het algemeen veel beter dan de ereg_* functies.quote:Op vrijdag 19 juni 2009 23:51 schreef Intrepidity het volgende:
[..]
Lekker goed voor de performance ook![]()
![]()
Aangezien de functionaliteit in php (afaik) niet bestaat om hoofdletterongevoelig te vergelijken maar vervolgens wel de hoofdletters te behouden zou ik er gewoon een eigen functietje voor maken:
[ code verwijderd ]
Stuk beter voor de performance dan een regular expression
Goed punt, het is ook al laatquote:Op zaterdag 20 juni 2009 00:08 schreef Light het volgende:
[..]
Ik ben het met je eens dat het sneller is als je geen regular expression nodig hebt. Maar van de regular expression functies presteren de preg_* functies over het algemeen veel beter dan de ereg_* functies.
En jouw functie is leuk, maar werkt alleen als de input een exacte match is met de compare-tekst (hoofdletters buiten beschouwing gelaten). Met preg_replace() mag er ook tekst voor en/of achter de gezochte tekst staan en kun je toch een goede vervanging maken.
Wat is een te verwachten waarde voor de straal? 1km? 10km? 100km? Dit is namelijk heel erg bepalend voor hoeveel procent van je records je terug zou kunnen krijgen. Bij 100km zou je in theorie bijna alle locaties terug kunnen krijgen, dus dan heeft slim querien weinig zin, bijvoorbeeld.quote:Op donderdag 18 juni 2009 17:30 schreef Likkende_Lassie het volgende:
Vraagje:
Ik heb de volgende functie om te berekenen hoeveel afstand er tussen 2 coordinaten zit:
[ code verwijderd ]
Echter, nu heb ik een database met +300.000 records.
Ik wil dat de gebruiker kan zeggen: ik wil binnen een straal van xx KM de resultaten zien.
Dat kunnen ze doen door een postcode in te vullen, waar ik een ander script voor heb om de coordinaten te berekenen.
Maar, om nu elk record te doorlopen om te kijken wat de afstand is, komt natuurlijk niet ten goede van de performance.
Weet iemand hoe ik het bovenstaande het beste kan berekenen? Ik heb in de database de coordinaten al opgeslagen. Dus ik zou eigenlijk in mijn mysql query kunnen zoeken op bijvoorbeeld: LIKE Lat = 1234'%' ,,, maar hoe dit te berekenen?
Niet waar, ook met MySQL 5.x niet:quote:Op zaterdag 20 juni 2009 10:44 schreef HenryHill het volgende:
Het voordeel is dat je deze vierkant rechtstreeks kan gebruiken in je query ("WHERE Lat between 51,201 and 51,323 and Long between 54.30 and 54.37") en dat dit geoptimaliseerd kan door de indexen op de Lat en Long kolommen.
quote:If a range scan is possible on some key, the optimizer will not consider using Index Merge Union or Index Merge Sort-Union algorithms. For example, consider this query
Hmm, volgens mij zou je dan het stuk over index intersections moeten quoten, en ik maak hieruit op dat MySQL dan wel beide indexen gebruikt?quote:Op zaterdag 20 juni 2009 11:23 schreef GlowMouse het volgende:
[..]
Niet waar, ook met MySQL 5.x niet:
[..]
De enige ongelijkheid die ik zie staan daar is er eentje op een primary key van een InnoDB-tabel. Dat zal er wel mee te maken hebben dat die key bij elke entry in de index op key_col1 opgeslagen wordt, en MySQL dus eigenlijk alleen de index op key_col1 hoeft te raadplegen en daarbij direct en 'gratis' de ongelijkheid kan checken.quote:Op zaterdag 20 juni 2009 11:40 schreef HenryHill het volgende:
[..]
Hmm, volgens mij zou je dan het stuk over index intersections moeten quoten, en ik maak hieruit op dat MySQL dan wel beide indexen gebruikt?
Oh, zo, ja dat zou ook kunnen.quote:Op zaterdag 20 juni 2009 11:46 schreef GlowMouse het volgende:
[..]
De enige ongelijkheid die ik zie staan daar is er eentje op een primary key van een InnoDB-tabel.
Ik heb een andere verklaringquote:Dat zal er wel mee te maken hebben dat die key bij elke entry in de index op key_col1 opgeslagen wordt, en MySQL dus eigenlijk alleen de index op key_col1 hoeft te raadplegen en daarbij direct en 'gratis' de ongelijkheid kan checken.
De meeste webapplicaties gebruiken dan ook geen coordinatenquote:Queries op grote tabellen die geen resultaat kunnen geven op basis van maximaal één index, vermijd ik zelf liever bij webapplicaties.
Maar wat doe je dan met die index op key_col1?quote:Op zaterdag 20 juni 2009 12:05 schreef HenryHill het volgende:
Ik heb een andere verklaringIk denk dat InnoDB zijn primary key index altijd 'clustered' maakt, d.w.z. dat de records fysiek geordend op primary key worden opgeslagen. En wanneer gegevens fysiek gesorteerd opgeslagen zijn, is het heel efficient om een range query uit te voeren: je zoekt het beginpunt, het eindpunt, en je retourneert alle rijen ertussenin.
Het feit dat je gegevens fysiek geordend zijn op key_col1 maakt dat de tabel al geindexeerd is - het heeft geen aparte opslagstructuur nodig. Je tabel is tevens je index, als het ware.quote:Op zaterdag 20 juni 2009 12:09 schreef GlowMouse het volgende:
[..]
Maar wat doe je dan met die index op key_col1?
Welke situatie heb je nu uitgeprobeerd dan?quote:edit: EXPLAIN geeft aan toch iets te doen met index_intersect. Vreemd, ik zou zeggen dat alleen de index op key_col1 gebruiken efficienter is.
Dankje, die werkte een stuk beter.quote:
Moet je dat niet met \b doen?quote:Op zaterdag 20 juni 2009 19:48 schreef splendor het volgende:
[..]
Dankje, die werkte een stuk beter.
Alleen heb ik met /b gezegd dat het alleen hele woorden moeten zijn, maar dat pakt ie niet erg.
Forum Opties | |
---|---|
Forumhop: | |
Hop naar: |