1. SQL优化
1.1. 索引优化
关键字与数据的映射关系称为索引(==包含关键字和对应的记录在磁盘中的地址==)。关键字是从数据当中提取的用于标识、检索数据的特定内容。
普通索引:对关键字没有限制
唯一索引:要求记录提供的关键字不能重复
主键索引:要求关键字唯一且不为null
- 建立基础索引:在where、order by、join字段上建立索引
- 索引会大幅提升查询效率,但是也会损耗查询后修改效率, insert 或 update 时有可能会重建索引 ,要注意兼顾平衡
- 不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库
- like “%str%” 不支持索引, "str%"号是支持索引的
- where条件中选择列上加了函数,没法利用索引
- 变量类型要正确,避免隐式转换造成没法利用索引
- 当查询结果是返回表中5%以内的数据时,应该走索引;当查询结果返回的是超过表中5%的数据时,应该走全表扫描
SELECT columnName , count(*) FROM tableName GROUP BY columnName ORDER BY 2 DESC
1.2. 存储引擎差异
选项 | MyISAM | Innodb |
---|---|---|
文件格式 | 数据和索引是分别存储的,数据.MYD,索引.MYI | 数据和索引是集中存储的,.ibd |
文件能否移动 | 能,一张表就对应.frm、MYD、MYI3个文件 | 否,因为关联的还有data下的其它文件 |
记录存储顺序 | 按记录插入顺序保存 | 按主键大小有序插入 |
空间碎片(删除记录并flush table 表名之后,表文件大小不变) | 产生。定时整理:使用命令optimize table 表名实现 | 不产生 |
事务 | 不支持 | 支持 |
外键 | 不支持 | 支持 |
锁支持(锁是避免资源争用的一个机制,MySQL锁对用户几乎是透明的) | 表级锁定 | 行级锁定、表级锁定,锁定力度小并发能力高 |
1.2.1. 锁扩展
- 表级锁(table-level lock):lock tables
, ... read/write,unlock tables , ... 其中read是共享锁,一旦锁定任何客户端都不可读; write是独占/写锁,只有加锁的客户端可读可写,其他客户端既不可读也不可写。锁定的是一张表或几张表。 - 行级锁(row-level lock):锁定的是一行或几行记录。
- 共享锁:select from
where <条件> LOCK IN SHARE MODE; 对查询的记录增加共享锁;select fromwhere <条件> FOR UPDATE;,对查询的记录增加排他锁。 这里值得注意的是:innodb的行锁,其实是一个子范围锁,依据条件锁定部分范围,而不是就映射到具体的行上; 因此还有一个学名:间隙锁。比如select * from stu where id < 20 LOCK IN SHARE MODE会锁定id在20左右以下的范围,你可能无法插入id为18或22的一条新纪录。
选择依据 如果没有特别的需求,使用默认的Innodb即可。 MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。 Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键保证数据完整性。比如OA自动化办公系统。
作者:公众号_程序员乔戈里
链接:https://juejin.im/post/5c2c53396fb9a04a053fc7fe