2013-04-08 55 views
1

我目前正在爲iOS應用程序修改所有的php服務。他們中的一個似乎非常快速地消耗我所有的3個cpu內核(而沒有其他的做)。 此服務將51個最近的「泡泡」(bulles)提取到用戶實際所在的位置。 這裏是我的PHP:使用php的高CPU消耗的Mysql請求

$sql="SELECT *, get_distance('$latitude','$longitude',latitude,longitude) AS proximite 
FROM bulles INNER JOIN 
(SELECT userId, userFirstName, userLastName, userName, userPictureUrl from user) AS users 
ON bulles.auteur = users.userId 
INNER JOIN interests 
ON bulles.interet1 = interests.id 
WHERE auteur = '$userID' 
OR auteur 
IN (
    SELECT followedId 
    FROM following 
    WHERE followerId = '$userID' 
) 
ORDER BY proximite 
LIMIT 51"; 

,這裏是我的存儲功能 「get_distance」:

FUNCTION `get_distance`(lat1 DOUBLE, lng1 DOUBLE, lat2 DOUBLE, lng2 DOUBLE) RETURNS double 
BEGIN 
    DECLARE rlo1 DOUBLE; 
    DECLARE rla1 DOUBLE; 
    DECLARE rlo2 DOUBLE; 
    DECLARE rla2 DOUBLE; 
    DECLARE dlo DOUBLE; 
    DECLARE dla DOUBLE; 
    DECLARE a DOUBLE; 

    SET rlo1 = RADIANS(lng1); 
    SET rla1 = RADIANS(lat1); 
    SET rlo2 = RADIANS(lng2); 
    SET rla2 = RADIANS(lat2); 
    SET dlo = (rlo2 - rlo1)/2; 
    SET dla = (rla2 - rla1)/2; 
    SET a = SIN(dla) * SIN(dla) + COS(rla1) * COS(rla2) * SIN(dlo) * SIN(dlo); 
    RETURN (6378137 * 2 * ATAN2(SQRT(a), SQRT(1 - a))); 
END 

每秒該服務請求10飽和的CPU。 我有INNER JOIN語句之前有問題,所以也許它來自那裏? 任何想法?

+0

先在'SELECT'前面使用'EXPLAIN'並檢查輸出或在這裏發佈。 – Rob 2013-04-08 14:10:19

+2

三層嵌套連接,子選擇和最外層表中使用的自定義函數,您想知道爲什麼它很慢?您可能希望查看PostgreSQL + PostGIS,它可以將位置查找移動到數據庫中,並且可能會優化它(索引等) – 2013-04-08 14:10:45

+1

IIRC最新版本的MySQL具有地理空間功能,儘管我沒有看過它們 – 2013-04-08 14:14:37

回答

3

MySQL'IN'效率很低(雖然是一個很好的構造),因爲對每一行重新處理查詢。即

IN (
    SELECT followedId 
    FROM following 
    WHERE followerId = '$userID' 
) 

將其替換爲FROM子句中的表。例如:

...FROM (SELECT followedId FROM following WHERE followerId = '$userID') AS whatever 
(then in the WHERE put) OR auteur = whatever.followedId... 

乾杯。

+0

謝謝! 雖然10個請求/秒使cpu飽和,但現在25個保持低於40%。 – r0dy 2013-04-08 15:09:05

+0

不用擔心隊友! – 2013-04-08 15:11:26