Reputation: 589
I create a table by
CREATE TABLE `part_tab` (
`id` int NOT NULL,
`use_time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY HASH(MONTH(use_time)) PARTITIONS 12;
then I use EXPLAIN PARTIONS syntax, but it seems that MySQL didn't use that partition, it still scans the whole table:
mysql> explain partitions select * from part_tab where use_time < '2013-02-01' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: part_tab
partitions: p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 12
Extra: Using where
1 row in set (0.00 sec)
if I change the where condition to equal,the partition is used:
mysql> explain partitions select * from part_tab where use_time = '2013-02-01' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: part_tab
partitions: p2
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 2
Extra: Using where
1 row in set (0.00 sec)
Upvotes: 2
Views: 2334
Reputation: 1269445
Your query is:
select *
from part_tab
where use_time = '2013-02-01';
Your partition statement is:
PARTITION BY HASH(MONTH(use_time)) PARTITIONS 12;
What you are trying to do is called "partition pruning". According to the documentation,
Pruning can also be applied for tables partitioned on a DATE or DATETIME column when the partitioning expression uses the YEAR() or TO_DAYS() function. In addition, in MySQL 5.7, pruning can be applied for such tables when the partitioning expression uses the TO_SECONDS() function.
I don't believe there is any way to do partition pruning directly on MONTH()
instead of YEAR()
. You can rewrite your query as:
select *
from part_tab
where month(use_time) = 1;
However, I suspect that range partitioning on the date is a better solution.
Upvotes: 1