最有效的方法来对程序结果进行查询

时间:2014-07-16 11:51:42

标签: php mysql performance stored-procedures procedure

感谢任何帮助。

我正在尝试根据MySQL PROCEDURE 生成的结果创建查询。我希望将此 PROCEDURE 修改为 JOIN 并在1个查询中执行此操作,但是从我读过的内容中我无法做到这一点,所以我是寻找最有效的方法来查询来自同一数据库但不同的表的信息,这些表由目的地的ID链接。

例如:查询地址表并获取按ID链接的每个PROCEDURE结果的每个地址

如果PROCEDURE返回50个不同的“目的地”或结果,有没有办法避免再进行50次额外查询?我假设最有效的方法是创建另一个程序。

PROCEDURE代码 - 此过程查询数据库并根据纬度和经度抓取点。数据由MAXMIND提供,可在此处找到:

https://www.maxmind.com/en/geolocation_landing

CREATE PROCEDURE `GEODIST`( IN userid int, IN dist int, IN olat float, IN olon float ) DETERMINISTIC READS SQL DATA

BEGIN
DECLARE mylon DOUBLE;
DECLARE mylat DOUBLE;
DECLARE lon1 FLOAT;
DECLARE lon2 FLOAT;
DECLARE lat1 FLOAT;
DECLARE lat2 FLOAT;

SET mylon = olon;
SET mylat = olat;
SET lon1 = mylon - dist / abs( cos( radians( mylat ) ) * 69 );
SET lon2 = mylon + dist / abs( cos( radians( mylat ) ) * 69 );
SET lat1 = mylat - ( dist / 69 );
SET lat2 = mylat + ( dist / 69 );

SELECT destination.id, destination.latitude, destination.longitude, 3956 * 2 * ASIN(SQRT( POWER(SIN((origin.latitude -destination.latitude) * pi()/180 / 2), 2) +COS(origin.latitude * pi()/180) * COS(destination.latitude * pi()/180) *POWER(SIN((origin.longitude -destination.longitude) * pi()/180 / 2), 2) )) AS distance FROM locations destination, locations origin WHERE origin.id = userid
AND destination.longitude BETWEEN lon1 AND lon2 AND destination.latitude BETWEEN lat1 and lat2 
HAVING distance < dist ORDER BY distance LIMIT 50;
END

请致电程序:

CALL GEODIST( $userid, $distance, $latitude, $longitude )

修改

目前,我已使用评论部分中的建议编辑了代码,但我仍然收到错误,仍在尝试创建PROCEDURE。我试图为目的地使用别名,在这种情况下照片表,但它会抛出错误:

错误:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'd, locations origin JOIN photos p ON d.id = p.lid WHERE origin.id = userid AND ' at line 18


CREATE PROCEDURE `GEODIST`( IN userid int, IN dist int, IN olat float, IN olon float ) DETERMINISTIC READS SQL DATA

BEGIN
DECLARE mylon DOUBLE;
DECLARE mylat DOUBLE;
DECLARE lon1 FLOAT;
DECLARE lon2 FLOAT;
DECLARE lat1 FLOAT;
DECLARE lat2 FLOAT;

SET mylon = olon;
SET mylat = olat;
SET lon1 = mylon - dist / abs( cos( radians( mylat ) ) * 69 );
SET lon2 = mylon + dist / abs( cos( radians( mylat ) ) * 69 );
SET lat1 = mylat - ( dist / 69 );
SET lat2 = mylat + ( dist / 69 );

SELECT d.id, d.name, d.address, d.latitude, d.longitude, d.category, d.type, p.lid, p.pid, 3956 * 2 * ASIN(SQRT( POWER(SIN((origin.latitude -d.latitude) * pi()/180 / 2), 2) +COS(origin.latitude * pi()/180) * COS(d.latitude * pi()/180) *POWER(SIN((origin.longitude -d.longitude) * pi()/180 / 2), 2) )) AS distance FROM locations d, locations origin JOIN photos p ON d.id = p.lid WHERE origin.id = userid
AND d.longitude BETWEEN lon1 AND lon2 AND d.latitude BETWEEN lat1 and lat2 
HAVING distance < dist ORDER BY distance LIMIT 50;
END

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,你刚才可以加入地址表吗?

SELECT destination.id, destination.latitude, destination.longitude, 
3956 * 2 * ASIN(SQRT( POWER(SIN((origin.latitude -destination.latitude) * pi()/180 / 2), 2) +COS(origin.latitude * pi()/180) * COS(destination.latitude * pi()/180) *POWER(SIN((origin.longitude -destination.longitude) * pi()/180 / 2), 2) )) 
AS distance 
FROM 
locations destination, 
locations origin,
LEFT JOIN
addressTable
ON addressTable.id = destination.id
WHERE 
origin.id = userid
AND destination.longitude BETWEEN lon1 AND lon2 
AND destination.latitude BETWEEN lat1 and lat2
HAVING distance < dist 
ORDER BY distance LIMIT 50;

没有数据很难测试,但我相信它就是这样。

为作者编辑编辑

在新代码中,您将替换以下内容:

FROM locations d, locations origin 
JOIN photos p ON d.id = p.lid 

使用相应的表格名称,应该是这样的:

FROM destination d, origin o,
JOIN photos p
ON d.id = p.lid

当我们使用别名时,我们只是说从表格中选择一些东西&#34;目的地&#34;但是让昵称命名为&#34; d&#34;所以我们没有一个很长的sql语句。

此外,在您想要的选择中,请使用与FROM子句中使用的相同的别名。例如:

SELECT destination.id, destination.latitude

应该是

SELECT d.id, d.latitude