优化分为两种
- 硬优化,公司掏钱升级硬件
- 软优化,在操作和设计数据库上个优化(表结构和sql语句)
接下来说的都为软优化
一、软优化
1.执行次数多的语句分类
- 查询密集型(DQL) -> 查询次数多
- 修改密集型(DML) -> 修改次数多
根据表的特性,去做专门的优化
2.查询累计插入和查询的数据条数
show global status like 'lnnodb_rows%';
3.千万条数据例子,存储过程,相当于封装的方法,最后call来调用封装的方法
/* 以下代码: 完成1000W条数据的插入 */
-- 1. 准备表
CREATE TABLE `user`(
id INT,
username VARCHAR(32),
`password` VARCHAR(32),
sex VARCHAR(6),
email VARCHAR(50)
);
-- 2. 创建存储过程,实现批量插入记录
DELIMITER $$ -- 声明存储过程的结束符号为$$
CREATE PROCEDURE auto_insert()
BEGIN
DECLARE i INT DEFAULT 1;
START TRANSACTION; -- 开启事务
WHILE(i<=10000000)DO
INSERT INTO `user` VALUES(i,CONCAT('jack',i),MD5(i),'male',CONCAT('jack',i,'@itcast.cn'));
SET i=i+1;
END WHILE;
COMMIT; -- 提交
END$$ -- 声明结束
DELIMITER ; -- 重新声明分号为结束符号
-- 3. 查看存储过程
SHOW CREATE PROCEDURE auto_insert;
-- 4. 调用存储过程
CALL auto_insert(); -- 插入1000W条数据花费:3m49s 304 ms
二、查询密集型优化
针对查询效率低的问题,进行优化:索引
索引:是帮助mysql高效获取数据的数据结构==(B+树)==
1.索引分类
- 主键(约束)索引 -> 唯一+非空+提高查询效率
- 唯一(约束)索引 -> 唯一+提高查询效率
- 普通索引 -> 仅提高查询效率
- 组合(联合)索引 -> 多个字段组成索引【联合主键索引、联合唯一索引、联合普通索引】
- 全文索引TEXT BIGTEXY -> Mysql全文索引引用较少,基本针对文档类数据会选solr、es等文档搜索类数 据库
- hash索引 -> 根据key - value 等值查询效率非常高,但不适合范围查询
2.创建索引语法,所有的都是以普通为基础扩展的
-- 创建普通索引
create index 索引名 on 表名(字段);
-- 创建唯一索引,创建唯一约束的时候自动添加
create unique index 索引名 on 表名(字段);
-- 创建普通组合索引
create index 索引名 on 表名(字段1,字段2,...);
-- 创建唯一组合索引
create unique index 索引名 on 表名(字段1,字段2,..);
-- 主键索引
-- 在创建pk主键的时候自动添加
注意:
- 在同一张表创建多个索引,要保证索引名不能重复
- 索引名字可以以 索引语法缩写_表名_字段的方式写
- 主键索引pk无法通过此方式创建
- 当表中数据量大时,建立索引需要花费更多时间(底层抽出数据,建立b+树放入索引)
3.在创建表后指定
三、关于索引扩展内容
1.索引能增强查询效率,那针对update以及insert以及delete也能增加效率吗?
不能增加效率,并且效率会更慢,因为改变的时候,索引也需要重新拉出来生成B+Tree
2.索引是不是越来越多就越来越好?
并不是,B+Tree会把根节点存放在内存中≈16kb,当索引越来愈多的时候,就有越来越多的B+Tree占物理内存
3.索引创建的原则
四、索引失效,注意索引只有在where中生效
当sql语句写的有问题的时候,会导致应该走索引查询B+Tree的结果变成查表了
- 使用模糊查询,会导致走表查询,所以最好使用全值查询
- 最左侧法则,使当使用联合索引,不写完全字段的时候,联合索引的顺序从左到右,最左最好是短且重复率低,全写完则无所谓
- 在索引列上进行运算操作会导致索引失效,如substr对索引字段修改
- 字符串不加单引号也会导致索引失效
- 使用or分割的条件, 如果前一个有索引后一个没有,则索引失效
- isNull 和 is ont null -> 当这个为条件的时候索引失效,所以能设置0,则补药设置null
- in走索引 not in 不走索引 -> 当这些为条件的时候,not in会导致从表中一个一个找,因为没指定列
关于性能
尽量减少使用覆盖索引select * ,会导致性能降低,
尽量写清楚字段 而不是使用 * 的方式,不然需要定位会费时间