使SQL查询更快

时间:2015-03-31 16:47:06

标签: php mysql pdo

有谁能告诉我如何更快地进行此查询?

$session_id = '000000000015';
$start = 0;
$finish = 30;

try {
    $stmt = $conn->prepare("SELECT TOPUSERS.ID, TOPUSERS.USERNAME, TOPUSERS.NAME, TOPUSERS.NAME2, TOPUSERS.PHOTO, TOPUSERS.FB_USERID, TOPUSERS.IMAGE_TYPE, TOPUSERS.TW_USERID, TOPUSERS.TW_PHOTO,

    COALESCE((SELECT COUNT(USERS_BUCKETS.ID) FROM USERS_BUCKETS WHERE USERS_BUCKETS.USERID=TOPUSERS.ID),0) AS NUM_ALL,
    COALESCE((SELECT SUM(CASE WHEN USERS_BUCKETS.STATUS='Completed' THEN 1 ELSE 0 END) FROM USERS_BUCKETS WHERE USERS_BUCKETS.USERID=TOPUSERS.ID),0) AS NUM_DONE,
    COALESCE((SELECT COUNT(USERS_LIKES.ID) FROM USERS_LIKES WHERE USERS_LIKES.USERID=TOPUSERS.ID),0) AS NUM_LIKES,

    (SELECT USERS_BUCKETS.BUCKETID FROM USERS_BUCKETS WHERE USERS_BUCKETS.USERID=TOPUSERS.ID ORDER BY USERS_BUCKETS.DATE_MODIFIED DESC LIMIT 1) AS RECENT_BUCKET,
    (SELECT BUCKETS_NEW.BUCKET_NAME FROM BUCKETS_NEW WHERE BUCKETS_NEW.ID=RECENT_BUCKET) AS REC,

    COALESCE((SELECT COUNT(ID) FROM FOLLOW WHERE FOLLOW.USER_ID=TOPUSERS.ID),0) AS FOLLOWING,
    COALESCE((SELECT COUNT(ID) FROM FOLLOW WHERE FOLLOW.FOLLOW_ID=TOPUSERS.ID),0) AS FOLLOWERS,

    (SELECT IF(TOPUSERS.NAME = '',0,1) + IF(TOPUSERS.BIO = '',0,1) + IF(TOPUSERS.LOCATION = '',0,1) + IF(TOPUSERS.BIRTHDAY = '0000-00-00',0,1) + IF(TOPUSERS.GENDER = '',0,1)) as COMPLETENESS,

    CASE WHEN ? IN (SELECT USER_ID FROM FOLLOW WHERE FOLLOW_ID = TOPUSERS.ID) THEN 'Yes' ELSE 'No' END AS DO_I_FOLLOW_HIM

    FROM TOPUSERS
    LEFT JOIN FOLLOW ON TOPUSERS.ID = FOLLOW.FOLLOW_ID
    LEFT JOIN USERS_BUCKETS ON USERS_BUCKETS.USERID=TOPUSERS.ID
    LEFT JOIN BUCKETS_NEW ON BUCKETS_NEW.ID=USERS_BUCKETS.BUCKETID

    WHERE NOT TOPUSERS.ID = ?

    GROUP BY TOPUSERS.ID ORDER BY TOPUSERS.RANDOM, TOPUSERS.USERNAME LIMIT $start, $finish");

当我在浏览器中运行它时,加载大约需要7秒钟。没有几行(中间的COALESCE,上面的两个SELECTS和它们下面的线),时间减少到3-4秒。

查询结果是一个包含姓名,个人资料图片和一些数据的人员列表。

1 个答案:

答案 0 :(得分:0)

TL,DR:您需要重写查询。

您需要重写查询以提高查询效率。我上周必须在工作中重写一个类似的查询,这就是我所做的。

您的查询结构应该看起来效率很高:

select ...
...
from ...
join ...
where ...

你现在拥有的是:

select ...
inner select
inner select
from ...
join ...
where ...

这是杀死你的查询的内部选择。您需要找到一种方法将内部选择移动到from部分。特别是你已经查询了表格。

您需要了解的是,您的内部选择会针对您拥有的每条记录运行。所以,如果你有10条记录,那就没问题了(速度明智)。但是有数百或数千条记录,这将是非常缓慢的。

如果您想了解有关查询的更多信息,请使用其中的explain关键字运行它。