sql优化和视图(四)
SQL优化
insert优化
- 批量插入
- 手动提交事务
- 主键顺序插入(顺序插入性能高于乱序插入)
大批量插入数据
若一次性需要插入大批量数据,使用insert语句插入性能较低,此时可使用mysql数据库提供的load指令进行插入。
- 客户端连接服务端,加上参数–local-infile
- mysql –local-infile -u -root -p
- 查看全局参数local_infile状态
- select @@local_infile
- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
- set global local_infile=1
- 执行load指令将准备好的数据,加载到表结构中
- load data local infile ‘数据存放的目录’ into table 表名 fields terminated by ‘数据中字段分割符号’ lines terminated by ‘\n’
主键优化
数据组织方式:在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表。
页分裂:页可以为空,也可填充一半,也可填充100%,每个页包含2-N行数据(若一行数据多大,会行溢出),根据主键排列。
页合并:当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记为删除且它的空间变得允许被其他记录声明使用。当页中删除额记录达到merge_threshold(合并页的阈值,默认为页的50%,可自己设置,在创建表或创建索引时指定),InnoDB会开始寻找最靠近的页(前或后)看看是否可将两个页合并以优化空间使用
主键设计原则:
- 满足业务需求的情况下,尽量降低主键的长度
- 插入数据时,尽量选择顺序插入,选择使用auto_increment自增主键
- 尽量不要用UUID做主键或是其他自然主键,如省份证号
- 业务操作时,避免对主键的修改
order by优化
排序方式:
- 通过对返回数据进行排序,也就是filesort排序,所有不是通过索引直接返回排序结果的排序豆角filesort排序
- 通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需额外排序,操作效率高
根据排序字段建立合适的索引,多字段排序时,也遵循最左侧前缀法则。
order by后边的多个排序字段要求尽量排序方式相同。
order by后边的多个排序字段顺序尽量和联合索引字段顺序一致。
尽量使用覆盖索引。
多字段排序,一个升序一个降序,需注意联合索引在创建时的规则(ASC/DESC)。
若不可避免的出现filesort,大数据量排序时,可适当增大排序缓冲区大小sort_buffer_size(默认256K)
group by优化
分组操作时,可通过索引来提高效率。
分组操作时,索引的使用也是满足最左前缀法则的。
limit优化
一般分页查询时,通过创建覆盖索引能够比较好地提高性能,可通过覆盖索引加子查询形式进行优化。
count优化
count用法:
- count(主键)
- InnoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层,服务层拿到主键后,直接按行进行累加(主键不可能为null)
- count(字段)
- 无not null约束:InnoDB引擎会遍历整张表把每一行的字段值都取出来,返回服务层,服务层判断是否为null,不为null,技术增加
- 有not null约束:InnoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加
- count(1)
- InnoDB引擎遍历整张表,但不取值,服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加
- count(*)
- InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加
按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count( * )。
尽量使用count( * )
update优化
InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则会从行锁升级为表锁。
视图
视图是一种虚拟存在的表,视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
简单来讲,视图只保存了查询的sql逻辑,不保存查询结果,所以我们在创建视图时,主要的工作就落在创建这条sql查询语句上。
基本语法
创建
create [or replace] view 视图名称[(列名列表)] as select [with[ cascaded|local] check option]
查询
查看创建视图语句:
show create view 视图名称;
查看视图数据:
select * from 视图名称…;
修改
方式一:
create [or replace] view 视图名称[(列表名称)] as select语句 [with[ cascaded|local] check option]
方式二:
alter view 视图名称[(列表名称)] as select语句 [with[ cascaded|local] check option]
删除
drop view [if exits] 视图名称 [,视图名称]…
检查选项
当使用with check option子句创建视图时,mysql会通过视图检查正在更改的每个行,例如:插入,更新,删除,以使其符合视图的定义,mysql允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为确定检查的范围,mysql提供cascaded和local两个选项,默认值为cascaded。
- cascaded
- 假设有两个视图,分别为v2,v1。v2视图是基于v1视图的,若在v2创建时指定检查选项为 cascaded,v1创建时未指定检查选项。 则在执行检查时,不仅会检查v2,还会级联检查v2的关联视图v1。
- local
- 假设有两个视图,分别为v2,v1。v2视图是基于v1视图的,若在v2创建时指定了检查选项为 local ,v1创建时未指定检查选项。 则在执行检查时,只检查v2,不检查v2的关联视图v1,若v1创建时指定检查选项,则v1v2都检查。
视图的更新
更新视图的前提是视图中的行与基础表中的行必须存在一对一的关系。
若视图包含以下任何一项,则视图不可更新:
- 聚合函数或窗口函数(sum(),min(),max(),count()等)
- distinct
- group by
- having
- union或者union all
视图的作用
- 简单
- 视图可简化用户对数据的理解,可简化操作,经常使用的查询可定义为视图,从而使得用户不必为以后的操作每次指定全部的条件
- 安全
- 数据库可以授权,但不能授权到数据库特定行和特定的列上,通过视图用户只能查询和修改他们所能见到的数据
- 数据独立
- 视图可帮助用户屏蔽真实表结构带来的影响