rows: 1002288[z5] Extra: Using where 1 row in set (0.00sec) 与分区函数使用列无关的查询条件 mysql>EXPLAIN PARTITIONS SELECT COUNT(*) FROMRPT_MALEVENTS WHERE ALERT_TYPE = 1\G; ***************************1. row *************************** id: 1 select_type: SIMPLE table: RPT_MALEVENTS partitions: p2011,p20110809,p20110810,p20110811,p20110812,p20110813,p20110814,p20110815,p20110816,p20110817,p20110818,pMax[z6] type: index possible_keys: NULL key: RECORD_DATETIME key_len: 8 ref: NULL rows: 17084274[z7] Extra: Using where; Using index 1 row in set (0.00sec) mysql> EXPLAINSELECT COUNT(*) FROM RPT_MALEVENTS WHERE ALERT_TYPE = 1\G; ***************************1. row *************************** id: 1 select_type: SIMPLE table: RPT_MALEVENTS type: index possible_keys: NULL key: RECORD_DATETIME key_len: 8 ref: NULL rows: 17082459 Extra: Using where; Using index 1 row in set (0.00sec) 采用分区函数使用的列 mysql> EXPLAINPARTITIONS SELECT COUNT(*) FROM RPT_MALEVENTS WHERE RECORD_DATE >'2011-08-09' AND RECORD_DATE < '2011-08-15'\G; ***************************1. row *************************** id: 1 select_type: SIMPLE table: RPT_MALEVENTS partitions: p20110810,p20110811,p20110812,p20110813,p20110814,p20110815[z8] type: range possible_keys:PRIMARY key: PRIMARY key_len: 3 ref: NULL rows: 3767081[z9] Extra: Using where; Using index 1 row in set (0.08sec) mysql> EXPLAINPARTITIONS SELECT COUNT(*) FROM RPT_MALEVENTS WHERE RECORD_DATE >'2011-08-09' AND RECORD_DATE < '2011-08-15'\G; ***************************1. row *************************** id: 1 select_type: SIMPLE table: RPT_MALEVENTS partitions: NULL type: range possible_keys:PRIMARY key: PRIMARY key_len: 3 ref: NULL rows: 8541229[z10] Extra: Using where; Using index 1 row in set (0.00sec) 删除数据,如果删除1整天的数据,由于我们采用按天分区, mysql> ALTER TABLERPT_MALEVENTS DROP PARTITION p20110809;[z11] Query OK, 0 rowsaffected (0.65 sec) Records: 0 Duplicates: 0 Warnings: 0 删除后包含索引的和数据的RPT_MALEVENTS#P#p20110809.ibd被删除了 如果采用传统的不分区的方式删除。 mysql> DELETE FROMRPT_MALEVENTS WHERE RECORD_DATE < '2011-08-10'; Query OK, 3929328rows affected (1 min 29.68 sec) 由此可见,删除整个分区内的数据还是很快的, 如果分区表采用传统的方式删除: mysql> DELETEFROM RPT_MALEVENTS WHERE RECORD_DATE< '2011-08-11'; Query OK, 1153866rows affected (19.72 sec) mysql> DELETE FROMRPT_MALEVENTS WHERE RECORD_DATE < '2011-08-11'; Query OK, 1153866rows affected (18.75 sec) 采用传统的方式删除一天的数据,用的时间都差不多。 只删除数据后,数据分区配p20110810还在,而且大小不变。可以用ALTER TABLE t1 OPTIMIZE PARTITION来进行回收,但是MySQL5.1.22还没有实现。 跨分区删除。 DELETE FROMRPT_MALEVENTS WHERE ALERT_TYPE =1; Query OK, 63969 rowsaffected (55.20 sec) DELETE FROMRPT_MALEVENTS WHERE ALERT_TYPE =1; Query OK, 63969 rowsaffected (50.26 sec) 分区表删除比不分区的略慢 [z1]分区函数 [z2]分区信息,从2011-08-09开始 [z3]没有用分区函数使用的列会扫描所有分区 [z4]数据量为681311,分区后扫描行数为355911,虽然查询条件没有分区函数的列,但是mysql的查询优化器会将其对应于时间分区,这样可以减少扫描行数 [z5]数据量为681311,分区后扫描行数为1002288 [z6]查找所有分区 [z7]无关分区函数的字段,会遍历几乎所有行。 [z8]扫描部分分区 [z9]扫描行数随之减少 [z10]估计扫描的行数 [z11]这个分区的数据是所有2011-8-10之前的所有数据,共3929328。
总结: 分区表是在MySQL5.1中新增的的功能,截止到MySQL5.1.22-rc,分区技术并不很成熟,很多分区的维护和管理功能未实现。如,分区内数据存储空间的回收、分区的修复、分区的优化等,MySQL的分区可以用在可以按分区删除的表中,且对数据库的修改操作不大,且频繁按 |