初探:
很长时间没写博客了,这两天一直在学习Mysql分区,总结下:
Mysql支持水平分区,并不支持垂直分区;
水平分区:指将同一表中不同行的记录分配到不同的物理文件中;
垂直分区:指将同一表中不同列的记录分配到不同的物理文件中;
其中CSV、FEDORATED、MERGE等引擎不支持分区,MYISAM、InnoDB、NDB等引擎支持分区
目的:
将一个表或索引分解为多个更小、更可管理的部分,从逻辑上讲,只有一个表或者索引,但是物理上这个表或者索引可能由数十个物理分区组成;没个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理(如果分区表很大,亦可以将分区分配到不同的磁盘上去);在执行查询的时候,优化器会根据分区定义过滤哪些没有我们需要数据的分区,这样查询就无须全表扫描所有分区,只查找包含需要数据的分区即可
适用场景:
1、表非常大以至于无法全部都放到内存,或者只在表的最后部分有热点数据,其他均为历史数据
2、分区表数据更容易维护(可独立对分区进行优化、检查、修复及批量删除大数据可以采用drop分区的形式等)
3、分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备
4、分区表可以避免某些特殊的瓶颈(ps: InnoDB的单个索引的互斥访问、ext3文件系统的inode锁竞争等)
5、可以备份和恢复独立的分区,非常适用于大数据集的场景
分区表限制:
- 单表最多支持1024个分区
- MySQL5.1只能对数据表的整型列进行分区,或者数据列可以通过分区函数转化成整型列;MySQL5.5的RANGE LIST类型可以直接使用列进行分区
- 如果分区字段中有主键或唯一索引的列,那么所有的主键列和唯一索引列都必须包含进来
- 分区表无法使用外键约束
- 分区必须使用相同的Engine
- 对于MyISAM分区表,不能在使用LOAD INDEX INTO CACHE操作
- 对于MyISAM分区表,使用时会打开更多的文件描述符(单个分区是一个独立的文件)
分区策略:
- 全量扫描数据,不需要任何索引:通过where条件大概定位哪个分区,必须将查询所需要扫描的分区个数限制在很小的数量
- 建立分区索引,分离热点:如将明显的热点数据分离到一个分区,使其尽量本文来源gaodai#ma#com搞@代~码^网+缓存到内存中,这样就能充分使用索引和缓存
注意:以上策略均以查询得到过滤,丢掉额外的分区,分区本身不产生额外的代价为准则】
分区表使用过程的坑坑:
- NULL值会使分区过滤无效:
分表的表达式的值可以是NULL,第一个分区为特殊分区存放NULL或者非法值
如: PARTITION BY RANGE YEAR(order_date)进行分区,那么order_date为NULL或者非法值,记录存放在第一个分区:
WHERE order_date BETWEEN ‘2014-01-01’ AND ‘2014-01-31’查询时会检查两个分区:
第一个分区及1月份分区,避免第一分区数据过大时造成查询代价过高,可以使用:建立第一分区专门存放order_date为NULL和非法值记录
PARTITION p_nulls VALUES LESS THAN(0)MySQL5.5以后可以才用一下语法解决问题:
PARTITION BY RANGE COLUMNS(order_date)
2.分区列和索引列不匹配
此种情况下查询无法进行分区过滤,分区失效除非查询中包含了可以过滤分区的条件
3.RANGE类型分区随着分区数量增加会对MYSQL额外增加查询分区定义列表(符合条件行在哪个分区)的压力,尽量限制适当的分区数量;key和hash类型分区不存在此问题