2013-04-02 35 views
2

我創建了由一個日期列的幾個月這樣分區的MySQL表:MySQL的分區修剪PARTITION BY LIST

CREATE TABLE `my_big_table` (
    `some_id` varchar(60) COLLATE utf8_unicode_ci NOT NULL, 
    `some_value` varchar(256) COLLATE utf8_unicode_ci NOT NULL, 
    `some_other_value` varchar(256) COLLATE utf8_unicode_ci NOT NULL, 
    `time` datetime NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 
PARTITION BY LIST(MONTH(time)) 
(PARTITION p1 VALUES IN (1) ENGINE = MyISAM, 
PARTITION p2 VALUES IN (2) ENGINE = MyISAM, 
PARTITION p3 VALUES IN (3) ENGINE = MyISAM, 
PARTITION p4 VALUES IN (4) ENGINE = MyISAM, 
PARTITION p5 VALUES IN (5) ENGINE = MyISAM, 
PARTITION p6 VALUES IN (6) ENGINE = MyISAM, 
PARTITION p7 VALUES IN (7) ENGINE = MyISAM, 
PARTITION p8 VALUES IN (8) ENGINE = MyISAM, 
PARTITION p9 VALUES IN (9) ENGINE = MyISAM, 
PARTITION p10 VALUES IN (10) ENGINE = MyISAM, 
PARTITION p11 VALUES IN (11) ENGINE = MyISAM, 
PARTITION p12 VALUES IN (12) ENGINE = MyISAM) 

現在,當我運行

explain partitions select * from my_big_table where month(time) = 2 limit 10; 

我得到的輸出:

id select_type table  partitions    type possible_keys key key_len ref rows  Extra 
1 SIMPLE  my_big_table p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 ALL NULL  NULL NULL NULL 10762868 "Using where" 

所以顯然所有的分區正在閱讀,我不知道爲什麼。不應該引擎足夠聰明以找出匹配值只能在分區p2?我得到相同的輸出爲基於日期的查詢,如

explain partitions select * from my_big_table where date(time) = '2013-02-01' limit 10; 

任何線索?

乾杯,亞歷克斯

回答

1

好了,經過一番更多的谷歌搜索和一些更多的嘗試和錯誤:
這個問題似乎是與月份(...)或日期(...)語句在哪裏我的查詢的子句。查詢

explain partitions select * from my_big_table where time = '2013-02-01 00:00:00' limit 10; 

只掃描分區P2預期。所以看起來像分區修​​剪只在分區列的原始值是where子句的一部分時才起作用。

乾杯,亞歷克斯

0

你永遠不應該使用的表值month(time) = 2功能,MySQL將永遠探討此類查詢所有的值(即全表掃描)。

通常情況下,您會發現這種與索引沒有被使用相關的「問題」,但分區修剪也是如此。

2

PARTITION BY RANGE之外的所有口味都沒用。當你有多個值時(特別是你發現的),情況尤其如此。

取而代之,考慮PARTITION BY RANGE(TO_DAYS(time))並使用WHERE time >= '2014-02-01' AND time < '2014-02-01' + INTERVAL 7 MONTH(作爲掃描一個月的示例)。請使用MONTH(time)

More discussion