一、分区表
分区表用于把相关数据放在一起,以分区为单位进行批量删除,检查/修复,备份/恢复等数据操作。当数据表非常大的时候,比如有10亿条记录,此时索引的空间、维护成本很高,全表扫描的成本更高;可以通过分区定位到某个数据区域,甚至可以把热点数据单独分区,使其有机会缓存到内存,并针对热点数据有效利用索引。可以认为分区是索引的初级版本。举个例子,可以把例年的销售数据放在不同分区;或者用键值分区,减少互斥量竞争。
可以通过SQL关键字partition by声明分区规则,创建分区表:create table sales (order_date, …) partition by range(year(order_dt)) (partition p_2018 values less than (2018), partition p_2018 values less than (2019), partition p_2020 values less than maxvalue);可以通过information schema.partitions查看分区情况;并通过explain partitions查看优化器是否进行了分区过滤。
分区表是一种逻辑表,由若干底层物理表组成,每个物理表对应一个句柄对象;对分区表的请求通过句柄对象转化为对存储引擎的接口调用。从文件系统来看,分区表有一个用#分隔命名的表文件。给分区表加索引则在各底层表加上相同的索引。操作分区表时会先打开并锁住所有底层表,优化器根据查询条件和分区表达式定位分区,因此为了有效利用分区,需要在查询中包含分区列
需要避免分区过多从而增大选择分区的成本。
二、视图
视图适用于对多个表的复杂查询,可以简化查询语句。此外可以在以下场景使用视图:1)重构schema的时候使用视图,修改底层表结构的同时,应用代码仍然基于视图运行;2)基于列的权限控制:读取某些列生成视图,并在视图上进行权限配置grant select on .. to user。
可以通过SQL关键字create view创建视图,如create view viewName as select * from table;
视图可以通过临时表算法或者合并算法生成:1)临时表算法更简单,把select结果存放到临时表,访问视图时直接访问临时表。临时表有性能问题,无法创建索引,并且例如select col from view jon tbl where condition,执行该查询时首先建立临时表,建表时不能应用condition过滤条件,数据范围大。2)合并算法是推荐算法:除了原表和视图记录无法建立一对一映射的情况(此时采用临时表算法),其他情况下Mysql默认使用合并算法。合并算法会重写含有视图的查询,把视图定义的sql直接合并到查询语句。通过explain可以看到临时表算法实现的视图显示为派生表derived;合并算法可以通过explain extended查看合并后的查询语句。
可以通过更新视图更新原表数据,但需要满足诸多前提条件。
视图的限制很多,如不能创建索引和trigger,不支持物化视图,即将视图结果保存在可查看的表中,并定期从原始表中刷新数据到这个表。总体而言,视图的性能不稳定,尽量避免在查询中使用视图
三、外键
InnoDB时Mysql中唯一支持外键的内置存储引擎。外键是有成本的,例如每次插入子表数据都要去父表执行一次查询,并对父表中的数据加锁,来确保该数据不会在这个事务完成前被删除;为此,InnoDB强制外键使用索引,但仍无法消除开销。外键通常作为性能的瓶颈,如果只作为约束,则通常更推荐在应用里实现约束。
四、Mysql内部存储代码
mysql内部存储代码是SQL的扩展,包含循环、分支等。Mysql允许通过触发器、存储过程、定时任务来存储代码。
优点在于帮助应用隐藏复杂性,把复杂的数据查询交给DBA并写在数据库里,但当前趋势是把复杂业务逻辑放在应用层;另外,在数据库服务器内部执行可以节省带宽和网络延迟,特别是用存储过程代替一系列小查询的情况;作为可重用代码;mysql服务层可以缓存存储过程的执行计划,对于反复调用的情况降低消耗等。缺点也很明显,没有开发调试工具,没有框架支持。
触发器:可配置在写操作执行前或者执行后触发一段代码,通常用于记录数据变更日志。InnoDB把触发器和SQL放在一个事务,如果触发器失败则sql语句也会失败。触发器基于一行数据,如果变更数据量很大则效率地下。
定时任务定时执行sql代码,又称为事件;通常把代码封装为存储过程进行调用。事件线程和连接线程独立,可通过information schema.events查看事件状态。
五、游标cursor
指向临时表中的数据,可以逐行指向查询结果;只读且单向,只能在存储过程或api中使用,
通过declare cursor声明,通过open/close cursor来打开或关闭;declare f cursor for select filmId from tbl; 打开游标时全表扫描tbl数据表,如果只需要扫描某些,推荐使用limit。
六、prepared statement
prepared statement用问号标记可以接收参数的位置,客户端发送sql语句原型给服务器,服务器存储该sql的执行计划并返回sql句柄,后续查询客户端发送句柄与参数值。
好处在于:1)有利于提高客户端和服务器间数据传输的效率(只需传输句柄和参数);2)解析器和部分优化器只需执行一次;3)提高安全性,无需在应用程序中注入参数,减少sql注入的风险。
限制:1)连接之间不能共用句柄;2)如果只执行一次sql,prepared statement会多出一次额外的准备执行阶段消耗。
七、插件
Mysql提供插件接口,为用户提供可扩展性。常见插件如:information schema插件可以提供一个新的information schema表;审计插件用于记录日志;存储过程插件;认证插件;全文解析插件提供分词功能,增强词语匹配功能;后台插件,实现网络监听,执行自定义定期任务。
网友评论