Hoi iedereen,

ik ben bezig met een systeem wat interessante opdrachten kan opleveren voor een gebruiker.
Zeg maar een "interessant voor u" systeem...

Hierbij moet rekening worden gehouden of de postcode van de opdracht valt binnen de straal
wat gelinkt is aan zijn account. En of het gekozen vakgebied waaronder de opdracht valt,
ook gekozen is binnen zijn vakgebieden pakket.

Onderstaand de code, het script werkt maar het is ontzettend traag... hoe kan ik dit beter aanpakken?

Hoor het graag van jullie!


<?php
$vakgebieden_SQL = mysql_query($vakgebieden_select);
		
	while($vakgebieden = mysql_fetch_array($vakgebieden_SQL)){
	echo "<h3>".$vakgebieden["vgebied_naam"]."</h3>";
					
						$postcode_a = str_replace(' ', '', preg_replace("/[^a-z0-9]/i", "", $user['gebruiker_postcode']));
						$postcode = substr_replace($postcode_a, ' ', 4, -2);
						// NAGELEGEN POSTCODES ZOEKEN ADHV DE STRAAL
						
						$rs = mysql_query("SELECT * FROM beheer_postcodes WHERE 6PP LIKE '%".$postcode."%'");
						
					
						if(mysql_num_rows($rs) == 0) {
						echo "Er werd geen postcode gevonden";
						
						} else {
						//if found, set variables
						$row = mysql_fetch_array($rs);
						$lat1 = $row['Lat'];
						$lon1 = $row['Lng'];
						$d = $pakket['pakket_straal'];
						//echo $postcode;
						//earth's radius in kms
						$r = 6371;
						
						//compute max and min latitudes / longitudes for search square
						$latN = rad2deg(asin(sin(deg2rad($lat1)) * cos($d / $r) + cos(deg2rad($lat1)) * sin($d / $r) * cos(deg2rad(0))));
						$latS = rad2deg(asin(sin(deg2rad($lat1)) * cos($d / $r) + cos(deg2rad($lat1)) * sin($d / $r) * cos(deg2rad(180))));
						$lonE = rad2deg(deg2rad($lon1) + atan2(sin(deg2rad(90)) * sin($d / $r) * cos(deg2rad($lat1)), cos($d / $r) - sin(deg2rad($lat1)) * sin(deg2rad($latN))));
						$lonW = rad2deg(deg2rad($lon1) + atan2(sin(deg2rad(270)) * sin($d / $r) * cos(deg2rad($lat1)), cos($d / $r) - sin(deg2rad($lat1)) * sin(deg2rad($latN))));
					
					
						$postcodes_SQL = mysql_query("SELECT * FROM beheer_postcodes WHERE (Lat <= ".$latN." AND Lat >= ".$latS." AND Lng <= ".$lonE." AND Lng >= ".$lonW.")");
						
						// QUERY SUFGGESTIES
						$suggesties_SQL = "SELECT o.*, p.* 
											FROM beheer_opdrachten o
											LEFT JOIN beheer_gebruikers p
											ON (p.gebruiker_randID = o.gebruiker_randID AND p.gebruiker_soort='2' AND o.opdracht_vgebied = '".$vakgebieden["vgebied_id"]."')
											WHERE o.opdracht_actief != '0' AND o.opdracht_gesloten != '1' 
											 "; 
										 
		
						while($postcodes = mysql_fetch_array($postcodes_SQL)){
						//echo $postcodes['6PP'];
						
						$suggesties_SQL .= " OR p.gebruiker_postcode LIKE '".$postcodes['6PP']."' 
						OR p.gebruiker_postcode LIKE '".str_replace(' ', '', $postcodes['6PP'])."' ";
						}
						
						
						$suggesties_SQL .= "";
						//echo $suggesties_SQL;
						$suggesties = mysql_query($suggesties_SQL);
						
						while($suggestie = mysql_fetch_array($suggesties)){
						
						echo $vakgebieden["vgebied_id"]." ".$suggestie['opdracht_titel'];
						echo "<br /><br />";
						}
						
						}
	}
?>

Voer de querie eens uit met EXPLAIN ervoor?
Dan moet er meer duidelijkheid komen (voor de kenners hier op het forum) of de query zelf de oorzaak is.
Hoi Aar,

Bedankt voor je bericht.
Heb de query uitgevoerd met EXPLAIN ervoor, krijg echter (vreemd genoeg) geen resultaat terug.
Ik ga ervan uit dat het ligt aan de query m.b.t. vergelijk van postcodes.
Hij gaat alle postcodes opzoeken vanaf de postcode van de gebruiker binnen een vooraf bepaalde straal.
Daarna gaat hij kijken of de postcode van de opdracht voorkomt in deze reeks opgezocht postcodes.

Het is ontzettend omslachtig volgens mij.. vandaar de vraag naar eenvoudigere manieren.

Groeten
Jeroen
Die query met EXPLAIN ervoor kan je het beste in phpMyAdmin uitvoeren(of de commandline, als je er bekend mee bent).
Ik hoef geen EXPLAIN te zien, er wordt een verschrikkelijke lange WHERE clause met OR's gevormd en MySQL moet die allemaal controleren voor iedere rij.
Maar het kan stukken simpeler:

SELECT
	o.*, /* jakkes */
	g.* /* en weer jakkes */
FROM
	beheerders_opdrachten o
JOIN
	beheerders_gebruikers g
	ON  g.gebruiker_randID = o.gebruiker_randID
JOIN
	beheer_postcode zip
	ON zip.6PP = g.gebruiker_postcode
WHERE
	zip.lat BETWEEN @latS AND @latN
		AND
	zip.lng BETWEEN @lonW AND @lonE
		AND	
	g.gebruiker_soort='2'

En hier ben ik het even kwijt want ik zie dat je ook nog eens iets met vakgebieden doet, maar die sql kan ik niet terug vinden.

Waar het op neer komt is dat je op zich al trage query in while lus binnen while lus uitvoert.

Ik begrijp ook niet waarom je LIKE gebruikt, vervang dit door =, en dan gebruik je ook nog eens op kolommen uit een tabel achter een LEFT JOIN, waardoor dit een INNER JOIN wordt (de reden waarom ik er direct een INNER JOIN van maak).

[size=xsmall]Toevoeging op 21/01/2015 21:07:43:[/size]

Als laatste opmerking, zorg dat je de postcodes eenduidig opslaat dus geen replace uit voeren in het script maar ervoor zorgen dat het goed in de tabel(len) staat.

Reageren