2013-04-23 162 views
1

我有一個關於MySQL性能的問題。 這些都是我的表:MySQL優化計數查詢

(約140.000記錄)

CREATE TABLE IF NOT EXISTS `article` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `label` varchar(256) COLLATE utf8_unicode_ci NOT NULL, 
    `title` varchar(256) COLLATE utf8_unicode_ci NOT NULL, 
    `intro` text COLLATE utf8_unicode_ci NOT NULL, 
    `content` text COLLATE utf8_unicode_ci NOT NULL, 
    `date` int(11) NOT NULL, 
    `active` int(1) NOT NULL, 
    `language_id` int(11) NOT NULL, 
    `category_id` int(11) NOT NULL, 
    `indexed` int(1) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=132911 ; 

(約400.000記錄)

CREATE TABLE IF NOT EXISTS `article_category` (
    `article_id` int(11) NOT NULL, 
    `category_id` int(11) NOT NULL 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

運行此統計查詢:

SELECT SQL_NO_CACHE COUNT(id) as total 
FROM (`article`) 
LEFT JOIN `article_category` ON `article_category`.`article_id` = `article`.`id` 
WHERE `article`.`language_id` = 1 
AND `article_category`.`category_id` = '<catid>' 

此查詢需要很多資源,所以我想知道如何優化這個查詢。 執行它的緩存後,所以在第一次運行後,我很好。

運行EXPLAIN功能:

enter image description here

後創建索引:

ALTER TABLE `article_category` ADD INDEX (`article_id` , `category_id`) ; 

enter image description here

添加索引和改變LEFT加入後加入查詢運行快得多! 感謝這麼快回信:)

QUERY我現在用的(我刪除了LANGUAGE_ID,因爲這並不是說neccesary):

SELECT COUNT(id) as total 
FROM (`article`) 
JOIN `article_category` ON `article_category`.`article_id` = `article`.`id` 
AND `article_category`.`category_id` = '<catid>' 

我讀過一些有關強制的指標,但我認爲是因爲這些表已經被編入索引,所以不再需要了吧?

非常感謝!

的Martijn

+0

向我們展示EXPLAIN的結果 2013-04-23 11:45:13

+0

在'article_category.article_id'上添加一個索引。 – Barmar 2013-04-23 11:45:33

+1

要麼你不應該做'LEFT JOIN',或者你需要在'ON'子句中測試'category_id = '。否則,您會過濾掉「article_categories」中沒有匹配的文章。 – Barmar 2013-04-23 11:50:11

回答

2

您沒有在表上創建索引所需

article_category - 上(article_id, category_id)

article建立複合索引 - 創建於(id, language_id)

一個複合索引。如果這沒有幫助發佈解釋說明。

1

JOIN條件中使用應該有一個索引,所以你需要指數article_id列。