2010-07-26 128 views
3

以前從未見過。運行相同的查詢,1強制索引。沒有索引,結果不正確(按錯誤順序),索引結果按正確的順序排列。只有使用索引的問題是由於某種原因,它更慢。指數是在COMMENT_ID和user_id說明與索引,返回不同的結果

沒有指數:

SELECT DISTINCT topic_id FROM comments 
WHERE user_id=9384 
AND (status = 1 or status = 0) 
ORDER BY comment_id DESC LIMIT 15 

搭配指數:

SELECT DISTINCT topic_id FROM comments force index(index_comment_user) 
WHERE user_id=9384 
AND (status = 1 or status = 0) 
ORDER BY comment_id DESC LIMIT 15 

任何想法?我真的想要得到正確的順序,而不會減慢查詢速度。我會通過索引來做到這一點。

這裏是SQL結構。

CREATE TABLE `db`.`comments` (
    `comment_id` int(10) unsigned NOT NULL auto_increment, 
    `old_comments_id` mediumint(8) unsigned default NULL, 
    `user_id` mediumint(8) unsigned default NULL, 
    `content` text character set latin1, 
    `status` tinyint(3) unsigned default NULL, 
    `added_date` datetime default NULL, 
    `category_id` tinyint(3) unsigned default NULL, 
    `helpful` tinyint(3) unsigned default NULL, 
    `modified_date` datetime default NULL, 
    `topic_id` mediumint(8) unsigned default NULL, 
    `last_mod_user_id` mediumint(8) unsigned default NULL, 
    PRIMARY KEY USING BTREE (`comment_id`), 
    KEY `Index_user_id` (`user_id`), 
    KEY `Index_added_date` (`added_date`), 
    KEY `Index_comments_status` USING BTREE (`status`), 
    KEY `Index_user_activity` USING BTREE (`comment_id`,`user_id`), 
    KEY `Index_user_activity2` USING BTREE (`user_id`,`topic_id`), 
    KEY `Index_question_id` USING BTREE (`topic_id`,`status`), 
    KEY `Index_user_activity3` (`user_id`,`status`,`topic_id`,`comment_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=2040237 DEFAULT CHARSET=utf8; 
+0

是MySQL的挑剔,在索引中的列的順序 - 如果你創建的user_id的指數Ie ,column_id會有幫助嗎? – Rup 2010-07-26 08:48:04

+0

請同時顯示確切的表格定義。 – Tomalak 2010-07-26 08:50:28

+0

添加了sql表結構 – David 2010-07-26 09:09:06

回答

2

如果在未選擇的列上使用DISTINCT和ORDER BY,將會出現問題。嘗試使用GROUP BY代替:

SELECT topic_id, MAX(comment_id) AS comment_id 
FROM comments 
WHERE user_id=9384 AND status IN (0, 1) 
GROUP BY topic_id 
ORDER BY comment_id DESC 
LIMIT 15 

您不應該強制索引。只需添加正確的索引,它應該自動使用。您可能想嘗試不同的組合和索引中列的排序,以查看最適合的列。

+0

但是,查詢很好。它不認爲我想獲得最近評論的主題。因此,我需要通過comment_id命令,而不是拋出一個不好的文件夾。 – David 2010-07-26 09:14:01

+0

「它不認爲我想得到最近評論的主題。」:我有min而不是max(我沒有注意到DESC)。這現在已經修復。 – 2010-07-26 09:27:20

+0

這並不能解決問題。我仍然需要這個命令。因爲您需要使用MAX註釋ID選擇主題,而不僅僅是前15個。所以ORDER BY comment_id不會,但會發生filesort。 – David 2010-07-26 09:41:15

0

manual says

如果表中有一個多列索引,該索引的任何最左前綴可以被優化用於查找行。例如,如果您在(col1,col2,col3)上有三列索引,則您在(col1),(col1,col2)和(col1,col2,col3)上具有索引搜索功能。

即我認爲你需要在user_id, column_id索引您的查詢 - 這聽起來並不像MySQL可以使用column_id, user_id。您應該在兩個查詢上運行EXPLAIN SELECT以驗證這一點。

爲什麼它與其他索引出錯我不知道對不起。

0

請提供我想知道,如果它的問題如果MAX(COMMENT_ID)別名是一列或名字不一樣的

EXPLAIN SELECT topic_id, MAX(comment_id) AS commentId 
FROM comments 
WHERE user_id=9384 AND status IN (0, 1) 
GROUP BY topic_id 
ORDER BY commentId DESC 
LIMIT 15 

結果。這是不明確的,你怎麼知道mysql是使用列還是聚合函數進行排序?

0

這是問題的常見的「最大值每個組」,通常是解決這樣的:

SELECT 
    comment.user_id, 
    comment.topic_id, 
    comment.comment_id 
FROM 
    comment 
    INNER JOIN (
     SELECT user_id, topic_id, MAX(comment_id) AS comment_id 
     FROM comments 
    GROUP BY user_id, topic_id 
) AS max ON max.comment_id = comment.comment_id 
WHERE 
    comment.user_id = 9384 
    AND comment.status IN (1, 0) 
ORDER BY 
    comment.comment_id DESC