2011-09-27 102 views
3

我有一個InnoDB MYSQL表,它存儲了一個多選擇名稱(或表中稱爲的「代碼」),一個父對象的id(parent_id)和多選中選擇的選項的名稱選擇(名_ID):在MySQL中加速DISTINCT查詢

CREATE TABLE IF NOT EXISTS `v2_CA_venue_option_map` (
    `map_id` int(11) NOT NULL auto_increment, 
    `code` varchar(30) NOT NULL, 
    `parent_id` int(11) NOT NULL, 
    `name_id` int(11) NOT NULL, 
    PRIMARY KEY (`map_id`), 
    UNIQUE KEY `3way_unique` (`code`,`parent_id`,`name_id`), 
    KEY `name_id` (`name_id`), 
    KEY `filter` (`code`,`name_id`), 
    KEY `parent_id` (`parent_id`), 
    KEY `code` (`code`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=875156 ; 

和一個簡單的表來存儲名字(我想我會證明這一點,因爲它在查詢中使用):

CREATE TABLE IF NOT EXISTS `v2_CA_venue_option_name` (
    `name_id` int(11) NOT NULL auto_increment, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`name_id`), 
    UNIQUE KEY `name` (`name`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Venue Option Names' AUTO_INCREMENT=60 ; 

,我想以優化以下查詢:

SELECT DISTINCT name_id, name 
FROM `v2_CA_venue_option_map` 
JOIN `v2_CA_venue_option_name` 
    USING (name_id) 
WHERE code = "a_event_types" 

這個查詢需要大約600毫秒來執行,我想知道:

  1. 如果我可以把索引放在桌上,以加快這一獨特的查詢。
  2. 我怎麼能得到相同的結果,更好的表現。

下面是對上述查詢的解釋。

enter image description here

UPDATE,我刪除了我的第二個問題。

更新,看起來最好的方法是將輸出存儲在一個單獨的表中,並從此開始調用該表,因爲此表無法足夠快地執行查詢因爲我的需求和索引似乎沒有幫助這個DISTINCT查詢。

+1

如果您有多個問題,您應該爲他們創建多個主題,因爲人們將更有可能提供幫助。 – Igor

+1

您也可能想要爲查詢粘貼解釋計劃。這將有助於瞭解MySQL的優化器在做什麼。 –

+0

運行此查詢需要多長時間並返回多少行? 'select name_id from v2_CA_venue_option_map where code =「a_event_types」group by name_id' – Karolis

回答

0

嘗試一個懶惰的group by而不是獨特的,它是MySQL不必擔心的一列。

SELECT name_id, name 
FROM `v2_CA_venue_option_map` 
JOIN `v2_CA_venue_option_name` 
    USING (name_id) 
WHERE code = "a_event_types" 
GROUP BY name_id 
+1

我正在研究,但如[這一個](http://stackoverflow.com/questions/581521/whats-faster-select-distinct-或 - group-by-in-mysql)的文章說,不同的是更快。 – RonSper

+0

沒錯,如果你對每一列進行分組,只嘗試對name_id進行分組。這個查詢給出了多少結果,順便說一句? –

+1

您的查詢在0.5153秒左右執行。這給出了19個結果。 – RonSper

0

您可以嘗試使用EXISTS將聯接查詢更改爲半聯接。無需DISTINCT

SELECT name_id 
    , name 
FROM v2_CA_venue_option_name AS n 
WHERE EXISTS 
     (SELECT * 
     FROM v2_CA_venue_option_map AS m 
     WHERE m.name_id = n.name_id 
      AND m.code = 'a_event_types' 
    ) 
+1

感謝您的建議。總計19次,查詢耗時5.6770秒,甚至接近DISTINCT的表現。 – RonSper

+0

你可以添加一個'(name_id,code)'索引嗎? –