1、分析和定位策略
2、优化
1、大批量插入数据,使用如下方式能快速导入大量数据(在 myisam 引擎下速度更为显著):
alter table 表名 disable keys;
Loading the data
Alter table 表名 enable keys;
2、优化 insert 语句:
3、优化 order by 语句:
4、优化 group by 语句:使用 group by null 可以避免用户排序结果的消耗
5、优化嵌套查询:子查询可以一次性完成多个步骤查询,同时可以避免事务或者是表死锁。但是在有些情况下,连接查询可以代替子查询
6、优化 or 条件:正确使用 or 条件查询,当时在对有独立索引的列查询时 or 操作能够快速查找到结果;而在对有复合索引的列上做 or 操作时,却不能用到索引
7、优化分页查询:
①思路一:在索引上完成排序分页的操作,最后根据主键关联回原表查询所需要的其他列内容,这种方式让 mysql 扫描尽可能少的页面来提高分页效率
②思路二:把 limit 查询转换成某个位置查询。这样把 limit m,n 转换成 limit n 只适合在排序字段不会出现重复值的环境下
8、使用 SQL 提示:
PS:索引问题
1、索引的存储分类
2、Mysql 中使用索引的场景
①匹配全值:对索引中所有列都指定具体值,即对索引中的所有列都有等值匹配的条件
例:select * from rental where rental_date=’2017-06-27 17:40:59’ and customer_id=343;
②匹配值的范围查询:对索引的值能够进行范围查找
例:select * from rental where customer_id>=373 and customer_id<400;
③匹配最左前缀:仅仅使用索引中的最左边列进行查找。
例:在 A+B+C 字段上的联合索引能够被 A、A+B、A+B+C 的等值查询利用,但是不能被 B、B+C 的等值查询利用到。
④仅仅对索引进行查询,档查询的列都在索引的字段中时,查询的效率更高
⑤匹配列前缀:仅仅使用索引中的第一列,并且只包含索引第一列的开头一部分进行查找
⑥索引匹配部分精确而其他部分进行范围匹配:
例:select a_id from rental where rental_date=’2006-02-14’ and customer_id >=300 and customer_id < 400
⑦如果列名是索引,那么使用 column_name is null 就会使用索引
3、存在索引但不能使用索引的场景
1、优化表的数据类型:表需要使用何种数据类型是需要根据应用来判断的。可以使用函数procedure analyse()对当前应用的表进行分析,可以根据当前表提出优化建议
2、通过拆分提高表的访问效率:
①垂直拆分:把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中
②水平拆分:根据一列或多列的值把数据行放到两个独立的表中
3、使用中间表提高统计查询速度:
①中间表复制源表部分数据,并且与源表相“隔离”,在中间表上做统计查询不会对在线用户产生负面影响
②中间表上可以灵活地添加索引或者增加临时用的新字段,从而达到提高统计查询效率和辅助统计查询作用
1、MySQL 的 3 种锁
①表(级)锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突概率最高,并发度最低(MyISAM,锁住整个表,可同时读,不可写)
②行(级)锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突概率最低,并发度也最高(InnoDB,单独的一行记录加锁)
③页面锁:开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行锁之间,并发度一般
行锁 | 表锁 | 页面锁 | |
---|---|---|---|
MyISAM | √ | ||
BDB | √ | √ | |
InnoDB | √ | √ |
2、MyISAM 的表级锁
①两种模式:
表共享读锁(所有用户可以同时去读同一个加了该表锁的表,但是不能去对其进行其他操作)
表独占写锁(一个用户在对加了该表锁的表进行写操作的时候,其他用户不能对其进行操作)。MyISAM 表的读操作与写操作之间,以及写操作之间是串行的,只允许上述其中一种操作进行
②加锁:MyISAM 在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执
行更新操作(UPDATE、DELETE、INSERT 等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,都是由 MyISAM 引擎自动完成加锁
③MyISAM 锁调度:MyISAM 存储引擎的读锁和写锁是互斥的,读写操作是串行的。当一个进程请求某个 MyISAM 表的读锁,同时另一个进程也请求同一表的写锁,此时 MySQL会让写进程先获得锁。不仅如此,即使读请求先到锁等待队列,写请求后到,写锁也会插到读锁请求之前
3、InnoDB 的锁
①几种锁模式:
共享锁(S 锁):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排它锁(X 锁):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。另外,为了允许行锁和表锁共存,实现多粒度锁机制
意向共享锁(IS 锁):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的 IS 锁。
意向排它锁(IX 锁):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的 IX 锁。
②加锁方式:意向锁是 InnoDB 自动加的,不需用户干预。对于 UPDATE、DELETE 和 INSERT 语句,InnoDB 会自动给涉及数据集加排他锁(X);对于普通 SELECT 语句,InnoDB 不会加任何锁。
③在不通过索引条件查询的时候,InnoDB 确实使用的是表锁,而不是行锁。
④由于 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突
⑤当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。
4、锁使用总结:
①表锁更适合与以查询为主,只有少量按索引条件更新数据的应用,如 Web 应用;
②行锁更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,入一些在线事务处理;
1、使用连接池
连接池:需要访问数据库的的地方,都已经预先创建好,可以直接获取链接,分配给应用使用,大大减少了创建新连接所耗费的资源。在访问结束后,链接将重新交还给连接池,以供新访问使用。
2、减少对 mysql 的访问
PS:第③个和第②个作用差不多,只是 cache 层比 query cache 要更大,层次要深点,cache 层可以看做是 mysql 的二级数据库,query cache 相当于 mysql 内部的缓存。
3、负载均衡:是重用的一种优化方式,采用某种均衡算法,将固定的负载量分布到不同的服务器上,以此来减轻单台服务器的负载均衡,达到优化的目的。
4、其他优化措施
概念补充