2015-03-31 79 views
-4

任何人都可以告诉我如何使此查询更快?使SQL查询更快

$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

这将**很**取决于数据库中的数据。 – D4V1D 2015-03-31 16:49:49

+0

我会说它作为一个批处理作业运行,并使其填充表...然后只需在Web应用程序中读取该表。 – developerwjk 2015-03-31 16:50:01

+0

这是一个VPS MYSQL 5,PHP 5.4.30 – erdomester 2015-03-31 16:52:58

回答

0

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

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

您的查询的结构应该像这样是有效的:

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

你现在有什么是一样的东西:

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

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

你需要了解的是,你的内部选择运行你有每个记录。所以,如果你有10条记录,这将是没问题的(速度明智)。但是,如果有成百上千的记录,它会非常缓慢。

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