MySQL YEAR(日期)上的分区错误结果

时间:2014-05-12 07:11:18

标签: mysql partitioning

我的表格定义如下:

CREATE TABLE `adverts_stats_clicks` (
 `advert_stats_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `advertisment_id` int(10) unsigned NOT NULL DEFAULT '0',
 `domain_id` int(10) unsigned NOT NULL DEFAULT '0',
 `catdom_id` int(10) unsigned NOT NULL DEFAULT '0',
 `added_on` date NOT NULL DEFAULT '0000-00-00',
 `ipfrom` varchar(64) NOT NULL DEFAULT '',
 `click_on` varchar(10) NOT NULL DEFAULT '',
 `click_from` varchar(5) NOT NULL DEFAULT '',
 `click_from_path` char(3) NOT NULL DEFAULT '',
 `country_id` int(11) NOT NULL DEFAULT '0',
 PRIMARY KEY (`advert_stats_id`,`added_on`),
 KEY `domain_id` (`domain_id`),
 KEY `click_on` (`click_on`),
 KEY `advertisment_id` (`advertisment_id`),
 KEY `country_id` (`country_id`),
 KEY `added_on` (`added_on`)
) ENGINE=MyISAM AUTO_INCREMENT=48176808 DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (YEAR(added_on))
(PARTITION ac0 VALUES LESS THAN (2005) ENGINE = MyISAM,
PARTITION ac1 VALUES LESS THAN (2006) ENGINE = MyISAM,
PARTITION ac2 VALUES LESS THAN (2007) ENGINE = MyISAM,
PARTITION ac3 VALUES LESS THAN (2009) ENGINE = MyISAM,
PARTITION ac4 VALUES LESS THAN (2010) ENGINE = MyISAM,
PARTITION ac5 VALUES LESS THAN (2011) ENGINE = MyISAM,
PARTITION ac6 VALUES LESS THAN (2012) ENGINE = MyISAM,
PARTITION ac7 VALUES LESS THAN (2013) ENGINE = MyISAM,
PARTITION ac8 VALUES LESS THAN (2014) ENGINE = MyISAM,
PARTITION ac9 VALUES LESS THAN (2015) ENGINE = MyISAM,
PARTITION ac99 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */

然后,如果我运行以下查询:

SELECT advert_stats_id 
  FROM adverts_stats_clicks 
 WHERE domain_id = 618 
   AND click_on = 'www' 
   AND click_from IN('sel','top','s','e','adv') 
   AND advertisment_id = 6122
   AND added_on BETWEEN '2012-10-01' AND '2014-12-31';

我得到152个结果。但是,如果我将日期范围更改为fllows:

SELECT advert_stats_id 
  FROM adverts_stats_clicks 
 WHERE domain_id = 618 
   AND click_on = 'www' 
   AND click_from IN('sel','top','s','e','adv') 
   AND advertisment_id = 6122
   AND added_on BETWEEN '2013-10-01' AND '2014-12-31';

我得到643个结果。这是无稽之谈,因为之前的日期范围大于第二个。 如果我运行说明分区,我会得到以下内容:

id  select_type     table   partitions  type    possible_keys   key     key_len     ref     rows    Extra   
1   SIMPLE  adverts_stats_clicks    ac7,ac8,ac9 index_merge     domain_id,click_on,advertisment_id,added_on     advertisment_id,domain_id   4,4     NULL    114     Using intersect(advertisment_id,domain_id); Using where

因此,在第一个查询中,选择了正确的分区(ac7,ac8,ac9)。这证明修剪工作正常。对于第二个查询,还选择了正确的分区(ac8,ac9),但两者检索的结果都不可信。

发生了什么事???为什么会这样?

来自服务器变量的一些额外信息,以防可能需要弄清楚。

Variable_name   Value   
character_set_client    utf8mb4
character_set_connection    utf8mb4
character_set_database  latin1
character_set_filesystem    binary
character_set_results   utf8mb4
character_set_server    latin1
character_set_system    utf8
character_sets_dir  /usr/share/mysql/charsets/

如果您需要更多信息以提供帮助,请提供帮助并提出其他问题。

谢谢!

1 个答案:

答案 0 :(得分:0)

当您使用BETWEEN'2013-10-01'和'2014-12-31'; 你检查两个字符串之间的值... '2013-10-01'将作为一个字符串......

所以,如果我们要检查日期..字符串应该转换为日期.. 使用str_to_date()函数