Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I have this table definition:

CREATE TABLE `va_ventas` (
`ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`Date` DATE NOT NULL,
`Time` TIME NULL DEFAULT NULL,
`Country` VARCHAR(3) NULL DEFAULT NULL,
`Type` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
`Result` TINYINT(3) UNSIGNED NULL DEFAULT NULL,
`Carrier` TINYINT(3) UNSIGNED NULL DEFAULT NULL,
`WM_Alias` VARCHAR(75) NOT NULL,
`Product_Code` VARCHAR(75) NOT NULL,
`Platform_Code` VARCHAR(40) NOT NULL,
`AltaID` MEDIUMINT(8) UNSIGNED NULL DEFAULT NULL,
`ClienteID` MEDIUMINT(8) UNSIGNED NULL DEFAULT NULL,
`Commission_Code` VARCHAR(40) NULL DEFAULT NULL,
INDEX `Date_WM_Alias_Product_Code` (`Date`, `WM_Alias`, `Product_Code`),
INDEX `Date_WM_Alias` (`Date`, `WM_Alias`),
INDEX `Date_Carrier_WM_Alias` (`Date`, `Carrier`, `WM_Alias`),
INDEX `AltaID` (`AltaID`),
INDEX `ClienteID` (`ClienteID`),
INDEX `Country` (`Country`),
PRIMARY KEY (`ID`, `Date`)
)
COLLATE='utf8_general_ci' ENGINE=MyISAM;

With the next partition schema:

PARTITION BY RANGE(TO_DAYS(Date)) 
(PARTITION p_2012_01 VALUES LESS THAN (TO_DAYS('2012-01-01')),
PARTITION p_2012_02 VALUES LESS THAN (TO_DAYS('2012-02-01')),
PARTITION p_2012_03 VALUES LESS THAN (TO_DAYS('2012-03-01')),
PARTITION p_2012_04 VALUES LESS THAN (TO_DAYS('2012-04-01')),
PARTITION p_2012_05 VALUES LESS THAN (TO_DAYS('2012-05-01')),
PARTITION p_2012_06 VALUES LESS THAN (TO_DAYS('2012-06-01')),
PARTITION p_2012_07 VALUES LESS THAN (TO_DAYS('2012-07-01')),
PARTITION p_2012_08 VALUES LESS THAN (TO_DAYS('2012-08-01')),
PARTITION p_2012_09 VALUES LESS THAN (TO_DAYS('2012-09-01')),
PARTITION p_2012_10 VALUES LESS THAN (TO_DAYS('2012-10-01')),
PARTITION p_2012_11 VALUES LESS THAN (TO_DAYS('2012-11-01')),
PARTITION p_2012_12 VALUES LESS THAN (TO_DAYS('2012-12-01')),
PARTITION p_2013_01 VALUES LESS THAN (TO_DAYS('2013-01-01'))
);

I filled the table with 10.000 dummy data entries and when I use EXPLAIN in a sample query I get the next result:

mysql> EXPLAIN PARTITIONS SELECT COUNT(*) FROM va_ventas WHERE Date BETWEEN '2012-08-01' AND '2012-10-20'\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: va_ventas
   partitions: p_2012_01,p_2012_09,p_2012_10,p_2012_11
         type: index
possible_keys: Date_WM_Alias_Product_Code,Date_WM_Alias,Date_Carrier_WM_Alias
          key: PRIMARY
      key_len: 7
          ref: NULL
         rows: 2591
        Extra: Using where; Using index

I don't know why it's using the p_2012_01 partition where it's not between the date specified in the BETWEEN statement. Also, shouldn't this select the partition p_2012_08 to match the statement? The data in the table is well distributed, so each date gets a similar amount of entries.

Thanks in advance.

EDIT

More information, I changed my partition schema to the next one, that makes more sense:

PARTITION BY RANGE(TO_DAYS(Date)) 
(PARTITION pNULL VALUES LESS THAN (0),
PARTITION p201201 VALUES LESS THAN (TO_DAYS('2012-02-01')),
PARTITION p201202 VALUES LESS THAN (TO_DAYS('2012-03-01')),
PARTITION p201203 VALUES LESS THAN (TO_DAYS('2012-04-01')),
PARTITION p201204 VALUES LESS THAN (TO_DAYS('2012-05-01')),
PARTITION p201205 VALUES LESS THAN (TO_DAYS('2012-06-01')),
PARTITION p201206 VALUES LESS THAN (TO_DAYS('2012-07-01')),
PARTITION p201207 VALUES LESS THAN (TO_DAYS('2012-08-01')),
PARTITION p201208 VALUES LESS THAN (TO_DAYS('2012-09-01')),
PARTITION p201209 VALUES LESS THAN (TO_DAYS('2012-10-01')),
PARTITION p201210 VALUES LESS THAN (TO_DAYS('2012-11-01')),
PARTITION p201211 VALUES LESS THAN (TO_DAYS('2012-12-01')),
PARTITION p201212 VALUES LESS THAN (TO_DAYS('2013-01-01')),
PARTITION p201301 VALUES LESS THAN (TO_DAYS('2013-02-01')),
PARTITION pMAX VALUES LESS THAN MAXVALUE
);

After filling, this is the status of the table:

SELECT PARTITION_NAME,TABLE_ROWS FROM 
INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'va_ventas';

+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| pNULL          |          0 |
| p201201        |        846 |
| p201202        |        793 |
| p201203        |        847 |
| p201204        |        820 |
| p201205        |        847 |
| p201206        |        819 |
| p201207        |        847 |
| p201208        |        847 |
| p201209        |        820 |
| p201210        |        847 |
| p201211        |        820 |
| p201212        |        847 |
| p201301        |          0 |
| pMAX           |          0 |
+----------------+------------+
15 rows in set (0.11 sec)


EXPLAIN PARTITIONS SELECT SQL_NO_CACHE 
COUNT(*) FROM va_ventas WHERE Date >= '2012-05-01' AND Date IS NOT NULL\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: va_ventas
   partitions: pNULL,p201205,p201206,p201207,p201208,p201209,p201210,p201211,p201212,p201301,pMAX
         type: index
possible_keys: PRIMARY,Date_WM_Alias
          key: PRIMARY
      key_len: 7
          ref: NULL
         rows: 6694
        Extra: Using where; Using index
1 row in set (0.00 sec)

It's still selecting the pNULL partition althought it's clearly that have 0 rows in it. Also, selection a date directly does not select the pNULL partition:

EXPLAIN PARTITIONS SELECT SQL_NO_CACHE COUNT(*) FROM va_ventas WHERE Date = '2012-05-01' AND Date IS NOT NULL\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: va_ventas
   partitions: p201205

Any thoughts?

share|improve this question
    
Does it remove the first partition if you change the query to: EXPLAIN PARTITIONS SELECT COUNT(*) FROM va_ventas WHERE Date BETWEEN '2012-08-01' AND '2012-10-20' AND Date IS NOT NULL\G; The reason I ask is because MySQL will put NULL values into the first partition (I realise that the column is NOT NULL, but it's worth checking). –  Phil Apr 11 '12 at 9:31
    
It does not... Any more ideas? –  Alberto Fernández Apr 11 '12 at 11:21
    
Yes. Why is accessing an empty partition a problem? :) –  Phil Apr 12 '12 at 17:35

2 Answers 2

The use of partitioning columns employing date or time types other than DATE or DATETIME is not supported with RANGE COLUMNS.

DATE and DATETIME. Columns using other data types relating to dates or times are not supported as partitioning columns.

share|improve this answer

sorry, the comment of @phil aroused my curiosity so I decided to cheat and to read the manual:

18.2.7. How MySQL Partitioning Handles NULL

Partitioning in MySQL does nothing to disallow NULL as the value of a partitioning expression, whether it is a column value or the value of a user-supplied expression. Even though it is permitted to use NULL as the value of an expression that must otherwise yield an integer, it is important to keep in mind that NULL is not a number. MySQL's partitioning implementation treats NULL as being less than any non-NULL value, just as ORDER BY does.

share|improve this answer
    
+1, exactly. A common strategy is to include a values less than (0) partition. While it will be included for a potential search; it will always be empty (or include the nulls you're looking for) –  atxdba Apr 12 '12 at 15:53
    
Still doing the same after adding MAXVALUE an (0) partitions, so I switched back to the original scheme. I don't know why, but it's adding always the partition in p_2012_01, and the adyacent partition to the last matched in the query, for example: EXPLAIN PARTITIONS SELECT SQL_NO_CACHE COUNT(*) FROM va_ventas WHERE Date BETWEEN '2012-05-01' AND '2012-06-10' AND WM_Alias IN ('HOLA', 'ALIAS2') AND Date IS NOT NULL; will select p_2012_01,p_2012_06,p_2012_07 partitions. –  Alberto Fernández Apr 12 '12 at 16:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.