Bug #47176 | PARTITION BY RANGE with TIMESTAMP is not pruning | ||
---|---|---|---|
Submitted: | 7 Sep 2009 14:57 | Modified: | 24 Oct 2012 11:12 |
Reporter: | Nuno Tavares | Email Updates: | |
Status: | Duplicate | Impact on me: | |
Category: | MySQL Server: Partitions | Severity: | S2 (Serious) |
Version: | 5.1.37 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | date, datetime, partition, range |
[7 Sep 2009 14:57]
Nuno Tavares
[7 Sep 2009 17:16]
Giuseppe Maxia
Thanks for your bug report. Verified as described, although the header was incorrect. It is only with TIMESTAMP that it doesn't prune. With DATETIME, it does fine. A partitioned table using timestamps partitioned by range doesn't prune on range selects. Simple test case follows: # first, using DATETIME create table t1 (dt datetime) partition by range (to_days(dt)) (partition p1 values less than (to_days('2009-01-01')), partition p2 values less than (to_days('2009-02-01'))); insert into t1 values ('2009-01-15 00:00:00'), ('2009-01-16 00:00:00'); explain partitions select * from t1 where dt between '2009-01-10 00:00:00' and '2009-01-20 00:00:00'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: p2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 2 Extra: Using where # next, using TIMESTAMPS alter table t1 modify dt timestamp; explain partitions select * from t1 where dt between '2009-01-10 00:00:00' and '2009-01-20 00:00:00'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: p1,p2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 2 Extra: Using where Workaround: replace TIMESTAMP with DATETIME and use a trigger to eventually insert current times.
[7 Sep 2009 17:58]
Nuno Tavares
What about using MONTH() on DATETIME? Should it be filed on separate bug report? mysql> CREATE TABLE `t1` ( -> `dt` datetime DEFAULT NULL -> ) ENGINE=InnoDB -> PARTITION BY RANGE (month(dt)) -> (PARTITION pJan VALUES LESS THAN (2) ENGINE = InnoDB, -> PARTITION pFeb VALUES LESS THAN (3) ENGINE = InnoDB, -> PARTITION pCatchAll VALUES LESS THAN MAXVALUE ENGINE = InnoDB); Query OK, 0 rows affected (0.02 sec) mysql> insert into t1 values ('2009-01-15 00:00:00'), ('2009-01-16 00:00:00'); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> explain partitions select * from t1 where dt BETWEEN '2009-01-01 01:00:00' AND '2009-02-02 01:00:00'\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t1 partitions: pJan,pFeb,pCatchAll type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4 Extra: Using where 1 row in set (0.00 sec) Thanks for pointing the correctness of subject, I was struggling with both (DATETIME and TIMESTAMP).
[7 Sep 2009 18:59]
Giuseppe Maxia
partition by range using MONTH() does not trigger the pruning. The manual says clearly that only YEAR and TO_DAYS are optimized for pruning. See my article on partitioning http://dev.mysql.com/tech-resources/articles/testing-partitions-large-db.html
[8 Sep 2009 14:28]
Mattias Jonsson
TIMESTAMP is not supported for pruning in TO_DAYS() or YEAR(). Implementing the pruning support would be possible, but since the handling of TIMESTAMP internally in the mysql server is affected by the session variable time_zone, TIMESTAMP is not deterministic for use in partitioning function and will probably be disallowed, see bug#42849.
[4 Aug 2012 1:27]
Rick James
I disagree. RANGE PARTITIONing on a TIMESTAMP can be DETERMINISTIC by defining that the value used for picking the PARTITION is the UTC equivalent of the TIMESTAMP given by the users. After all, that is what is stored. Furthermore, it can and should be treated as monotonic. (OK, I don't have an answer for what to do about Leap seconds; just make a rule.)
[24 Oct 2012 11:12]
Mattias Jonsson
Fixed in 5.5+ by bug#28928.