2015-03-31 76 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中的關鍵字運行它。