在MySQL Partitioned表上选择没有选择正确的分区

时间:2013-05-24 14:28:20

标签: mysql select partitioning

这是关于MySQL 5.5

我有这张桌子:

CREATE TABLE IF NOT EXISTS isup_trace_test (
             id int(11) NOT NULL AUTO_INCREMENT,
             datetime datetime DEFAULT NULL,
             microseconds int(11) DEFAULT NULL,
             opc int(11) DEFAULT NULL,
             dpc int(11) DEFAULT NULL,
             slc int(11) NOT NULL,
             operation varchar(45) DEFAULT NULL,
             release_text varchar(45) DEFAULT NULL,
             release_code int(11) DEFAULT NULL,
             calling varchar(45) DEFAULT NULL,
             nrn varchar(10) DEFAULT NULL,
             called varchar(45) DEFAULT NULL,
             cic int(11) DEFAULT NULL,
             message text,
             filename varchar(100) NOT NULL,
             PRIMARY KEY (id,datetime),
             UNIQUE KEY opc (opc,dpc,cic,operation,datetime,microseconds),
             KEY indice (datetime,microseconds,operation,cic,calling,called),
             KEY cic_datetime (cic,datetime,microseconds),
             KEY calling (calling),
             KEY called (called),
             KEY both_a_and_b (datetime,calling),
             KEY by_release_text (release_text),
             KEY by_release_code (release_code),
             KEY operation (datetime,operation),
             KEY per_opc (datetime,opc,dpc,operation),
             KEY for_search (cic,operation,datetime),
             KEY for_search_2 (datetime,calling,operation),
             KEY for_search_3 (datetime,called,operation),
             KEY search_1 (opc,dpc,cic,operation,datetime),
             KEY por_fecha (datetime),
             KEY tata (datetime,opc,dpc),
             KEY datetime_calling_called_operation (datetime,calling,called,operation),
             KEY filename (filename)
           ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 
           PARTITION BY LIST( HOUR(datetime) )(
               PARTITION p00 VALUES IN (0)  ,
               PARTITION p01 VALUES IN (1)  DATA DIRECTORY='/mnt/disk2' INDEX DIRECTORY='/mnt/disk2',
               PARTITION p02 VALUES IN (2)  DATA DIRECTORY='/mnt/disk3' INDEX DIRECTORY='/mnt/disk3',
               PARTITION p03 VALUES IN (3)  DATA DIRECTORY='/mnt/disk4' INDEX DIRECTORY='/mnt/disk4',
               PARTITION p04 VALUES IN (4)  DATA DIRECTORY='/mnt/disk5' INDEX DIRECTORY='/mnt/disk5',
               PARTITION p05 VALUES IN (5)  DATA DIRECTORY='/mnt/disk6' INDEX DIRECTORY='/mnt/disk6',
               PARTITION p06 VALUES IN (6)  ,                                                        
               PARTITION p07 VALUES IN (7)  DATA DIRECTORY='/mnt/disk2' INDEX DIRECTORY='/mnt/disk2',
               PARTITION p08 VALUES IN (8)  DATA DIRECTORY='/mnt/disk3' INDEX DIRECTORY='/mnt/disk3',
               PARTITION p09 VALUES IN (9) DATA DIRECTORY='/mnt/disk4' INDEX DIRECTORY='/mnt/disk4',
               PARTITION p10 VALUES IN (10) DATA DIRECTORY='/mnt/disk5' INDEX DIRECTORY='/mnt/disk5',
               PARTITION p11 VALUES IN (11) DATA DIRECTORY='/mnt/disk6' INDEX DIRECTORY='/mnt/disk6',
               PARTITION p12 VALUES IN (12) ,                                                        
               PARTITION p13 VALUES IN (13) DATA DIRECTORY='/mnt/disk2' INDEX DIRECTORY='/mnt/disk2',
               PARTITION p14 VALUES IN (14) DATA DIRECTORY='/mnt/disk3' INDEX DIRECTORY='/mnt/disk3',
               PARTITION p15 VALUES IN (15) DATA DIRECTORY='/mnt/disk4' INDEX DIRECTORY='/mnt/disk4',
               PARTITION p16 VALUES IN (16) DATA DIRECTORY='/mnt/disk5' INDEX DIRECTORY='/mnt/disk5',
               PARTITION p17 VALUES IN (17) DATA DIRECTORY='/mnt/disk6' INDEX DIRECTORY='/mnt/disk6',
               PARTITION p18 VALUES IN (18) ,                                                        
               PARTITION p19 VALUES IN (19) DATA DIRECTORY='/mnt/disk2' INDEX DIRECTORY='/mnt/disk2',
               PARTITION p20 VALUES IN (20) DATA DIRECTORY='/mnt/disk3' INDEX DIRECTORY='/mnt/disk3',
               PARTITION p21 VALUES IN (21) DATA DIRECTORY='/mnt/disk4' INDEX DIRECTORY='/mnt/disk4',
               PARTITION p22 VALUES IN (22) DATA DIRECTORY='/mnt/disk5' INDEX DIRECTORY='/mnt/disk5',
               PARTITION p23 VALUES IN (23) DATA DIRECTORY='/mnt/disk6' INDEX DIRECTORY='/mnt/disk6'
           )

现在选择分区的想法是让select只搜索相关分区,我希望如此:

EXPLAIN PARTITIONS SELECT * 
FROM isup_trace_test PARTITION (p18)
use index (operation)
WHERE
hour(datetime) = "18" and
DATETIME >= '2013-05-23 18:07:59' AND DATETIME <= '2013-05-23 18:37:59' AND 
operation =  'Release (12)'

返回类似的内容:

id  select_type table   partitions  type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  isup_trace_test p19 range   operation   operation   56  NULL    24  Using where

但事实上它会回归:

id  select_type table   partitions  type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  isup_trace_test p00,p01,p02,p03,p04,p05,p06,p07,p08,p09,p10,p11,p1...   range   operation   operation   56  NULL    24  Using where

意味着它将搜索所有分区....但它应该只搜索分区“p19”...

我做错了什么?

谢谢!

大卫

1 个答案:

答案 0 :(得分:0)

如果您查看MySQL5.5的文档,那么您将找到以下行,

当分区表达式使用YEAR()或TO_DAYS()函数时,

Pruning can also be applied for tables partitioned on a DATE or DATETIME column。此外,在MySQL 5.5中,当分区表达式使用TO_SECONDS()函数”时,可以对这些表应用修剪“< / p>

这意味着您用于分区的函数“HOUR()”未针对分区修剪进行优化。

据我所知,你的表分区还有一个设计缺陷。 有关using unique constraints with partitioning的规则。简而言之,你不能对你没有分区的东西有一个独特的约束。原因是当您插入记录并且需要检查唯一性时,我们不希望搜索每个分区以验证唯一性。索引是分区的本地(全局索引可能在将来实现)。因此,如果约束中的所有列都用在分区表达式中,则只能有唯一约束。

如果主键确实不重要,您可以决定放弃主键,否则它会使您的主键插入表中。

希望这可以帮助您理解问题。

相关问题