2013-04-29 42 views
1

我有什麼看起來像一個相當簡單的表結構,但MySQL是一個簡單的查詢默認爲不到最佳index_merge爲什麼MySQL在這個查詢上顯示index_merge?

這裏的表結構:

CREATE TABLE IF NOT EXISTS `event_log` (
    `event_id` int(11) NOT NULL AUTO_INCREMENT, 
    `user_id` int(5) DEFAULT NULL, 
    `location_id` int(10) DEFAULT NULL, 
    `object_id` int(5) DEFAULT NULL, 
    `action_id` int(5) DEFAULT NULL, 
    `date_event` datetime DEFAULT NULL, 
    PRIMARY KEY (`event_id`), 
    KEY `user_id` (`user_id`), 
    KEY `date_event` (`date_event`), 
    KEY `action_id` (`action_id`), 
    KEY `object_id` (`object_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

EXPLAIN一個基本SELECT查詢

EXPLAIN SELECT date_event 
FROM event_log 
WHERE user_id =123 
AND object_id =456 
AND location_id =789 

返回此:

select_type table  type   possible_keys  key     key_len  ref  rows Extra 
SIMPLE  event_log index_merge user_id,object_id object_id,user_id 5,5   NULL 27  Using intersect(object_id,user_id); Using where 

這裏的額外位,以方便您閱讀:

Using intersect(object_id,user_id); Using where 

爲什麼MySQL不在這個查詢中使用標準索引?它爲什麼相交user_idobject_id

回答

4

查詢的最有效索引是一個包含所有三個字段的組合索引,例如:(object_id, user_id, location_id)。由於沒有這樣的索引,MySQL會盡最大努力從現有索引中獲取大部分信息。

+0

這很好用。感謝您的解釋。 – 2013-04-29 21:43:38

+0

性能不好嗎?我是否使用個別索引進行合成? – Toleo 2018-02-10 17:12:59

+0

@toleo,在這樣一個簡單的查詢中,mysql可以猜測它可以合併索引並使用它們,但更常見的是它沒有,並且最好具有所需列的良好索引。性能取決於許多因素。一個索引允許RDBMS遍歷整個數據的一個排序後的較小的子集,通常速度較快,但索引消耗內存,這可能會影響其他方面的性能。 – newtover 2018-02-10 19:31:10