2014-02-27 47 views
1

這裏是我的查詢,當我使用高偏移量時,它會相當慢,爲什麼?這有什麼解決辦法嗎?使用高偏移量時查詢速度相當慢

offset 15 => 0.9747 seconds 

    SELECT `users`.*, count(`user_bets`.`id`) as bets, count(`user_bet_details`.`id`) as wins 
    FROM `users` 
    LEFT JOIN `user_bets` ON `user_bets`.`user_id` = `users`.`id` 
    LEFT JOIN `user_bet_details` ON `user_bet_details`.`user_id` = `users`.`id` and `user_bet_details`.`status` = 1 
    GROUP BY `users`.`id` 
    LIMIT 15, 10 

offset 2510 => 26.2188 seconds 

SELECT `users`.*, count(`user_bets`.`id`) as bets, count(`user_bet_details`.`id`) as wins 
    FROM `users` 
    LEFT JOIN `user_bets` ON `user_bets`.`user_id` = `users`.`id` 
    LEFT JOIN `user_bet_details` ON `user_bet_details`.`user_id` = `users`.`id` and `user_bet_details`.`status` = 1 
    GROUP BY `users`.`id` 
    LIMIT 2510, 10 

回答

3

的速度差可能從該服務器必須生成滿足查詢的行數來。對於第一種情況,它只需要生成25行結果集。第二,它必須產生2520行。由於訂單顯然不重要(基於查看指定查詢),也許可以將其更改爲使用用戶標識值(假設其以可預測的方式遞增)執行「分頁」。添加一個WHERE子句,指定感興趣的用戶ID範圍並放棄LIMIT子句。例如,可能是這樣的:

SELECT `users`.*, count(`user_bets`.`id`) as bets, count(`user_bet_details`.`id`) as wins 
    FROM `users` 
    LEFT JOIN `user_bets` ON `user_bets`.`user_id` = `users`.`id` 
    LEFT JOIN `user_bet_details` ON `user_bet_details`.`user_id` = `users`.`id` 
       and `user_bet_details`.`status` = 1 
    WHERE `users`.`id` >= 1 and `users`.`id` <= 10 
    GROUP BY `users`.`id` 

這可能是更有效地運行,但更棘手的行所需數量,如果id不加1(這似乎可能)。您仍然可以每次使用LIMIT子句和更大的範圍,然後在下一次調用時適當地指定下限(同樣我假設這是針對分頁結果)。

但在此之前,您可能會在查詢中輸入check the optimization。例如,如果連接表上沒有索引(特別是user_bets.user_iduser_bet_details.user_iduser_bet_details.status),那麼這可能會產生巨大的差異。我並沒有真正考慮開始時指定的時間,但是生成該查詢的26秒似乎非常長。聽起來好像有些索引可能需要創建。