2016-07-31 59 views
0

我正在使用以下SQL查詢以從數據庫獲取最新數據。獲取最新數據 - 優化SQL查詢

SELECT d.id AS id_d, 
     d.id_user AS id_du, 
     d.id_channel AS id_dc, 
     d.datetime_logged AS logged 

FROM discord AS d 
JOIN discord_users AS du 
ON d.id_user = du.id 
WHERE datetime_logged IN (SELECT MAX(datetime_logged) FROM discord) 
ORDER BY du.data_name ASC 

而這裏的數據庫中的模樣:

CREATE TABLE IF NOT EXISTS `discord` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `id_user` int(11) NOT NULL, 
    `id_channel` varchar(50) NOT NULL, 
    `id_game` int(11) NOT NULL, 
    `data_muted_server` tinyint(4) NOT NULL, 
    `data_muted_self` tinyint(4) NOT NULL, 
    `data_deafen_server` tinyint(4) NOT NULL, 
    `data_deafen_self` tinyint(4) NOT NULL, 
    `data_suppressed` tinyint(4) NOT NULL, 
    `data_status` varchar(10) NOT NULL, 
    `data_game` text, 
    `datetime_logged` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id` (`id`) 
) 

CREATE TABLE IF NOT EXISTS `discord_users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `data_id` text NOT NULL, 
    `data_name` varchar(50) NOT NULL, 
    `data_avatar` text, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id` (`id`) 
) 

該查詢以 「年齡」 來加載。但是,如果我刪除WHERE datetime_logged IN (SELECT MAX(datetime_logged) FROM discord)並將LIMIT 10添加到查詢中,則頁面加載速度非常快!


SQL查詢的目的是僅從表discord獲取最新數據。由於數據只會每15分鐘更新一次,因此查詢將輕鬆獲取最新數據。

discorddiscord_users的關係是discord需要從discord_users的ID以獲取用戶的信息。

要回答symcbean的問題futhermore:

Q)爲什麼,當你aapparently限制輸出中基於關係的「多」方的內容單一的記錄,你在訂購「一邊?

A)你是什麼意思?

Q)爲什麼在沒有差分索引的情況下在discord_users表上打開2個遊標?

A)再次,你是什麼意思? :)


所以這裏是我的問題。我怎樣才能優化我的SQL查詢,所以它不需要花費將近1分鐘來加載頁面?這裏有一個鏈接的網頁:https://erik-edgren.nu/discord

+2

你有索引'datetime_logged'嗎? –

+0

對不起,但我不知道究竟是什麼意思。請看我更新的問題。 – Erik

+0

有關更多信息,請參閱[本](http://dev.mysql.com/doc/refman/5.7/en/optimization-indexes.html)。 –

回答

0

如果您仍然有問題試試這個選項。創建INDEX表示例如index_datelogdatetime_loggeddiscord表。然後嘗試下面的查詢

SELECT 
    d.id AS id_d, d.id_user AS id_du, d.id_channel AS id_dc, d.datetime_logged AS logged 
FROM 
    discord d 
JOIN 
    discord_users du ON d.id_user = du.id USE INDEX(index_datelog)) 
WHERE 
    d. datetime_logged = (SELECT MAX(datetime_logged) FROM discord) 
ORDER BY d.datetime_logged ASC 
+0

感謝您的回答。我創建了索引(這比我想象的要容易得多,昨晚我一定已經太累了),並且現在使用我的SQL查詢加載頁面的速度非常快。您的查詢會導致錯誤; '致命錯誤:帶有消息'SQLSTATE [42000]的未捕獲異常'PDOException':語法錯誤或訪問衝突:1064您的SQL語法錯誤;檢查與您的MySQL服務器版本相對應的手冊,以找到在'(INDEX(index_datelog))附近使用的正確語法。 datetime_logged =(SELECT MAX(datetime_l'at'7''in' – Erik

+0

)哦!謝謝你指點。這是MSSQL的語法。用MySql語法更新答案 – jonju

+0

強制索引是非常糟糕的做法,不應該是必要的。它證明是必要的,但只有在經驗證據的支持下),同樣一個散列索引是無用的 - 它需要一個BTree索引,並且排序也從原始查詢改變。 – symcbean