在创建表时,指定存储引擎
create table 表名(
......
)engine=innodb;
查看当前数据库支持的存储引擎:
show engines;
存储引擎的特点
索引:一种高效查询的数据结构
B-Tree:
B+Tree:所有的数据都会出现在叶子节点,并且叶子节点形成一个单向链表
MySQL索引数据结构对B+Tree进行了优化,在其基础上,增加了一个指向相邻叶子节点的链表指针,形成了带有顺序指针的B+Tree,提高区间访问的性能
为什么InnoDB存储引擎选择使用B+Tree索引结构?
CREATE [UNIQUE | FULLTEXT] INDEX 索引名 ON 表名(字段1,字段2…)
SHOW INDEX FROM 表名
DROP INDEX 索引名 ON 表名
MySQL客户端连接成功后,通过 show [session|global] status
命令可以提供服务器状态信息。通过如下指令,可以查看当前数据库的 增删改查的访问频率
> SHOW GLOBAL STATUS LIKE ‘Com_______’;
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。
MySQL的慢查询日志默认没有开启
,需要在配置文件 my.cnf
中配置如下信息
查看慢查询日志的开启状态:show variables like ‘slow_query_log’;
show profiles 能够在做SQL优化时间帮助我们了解消费的时间,通过 have_profiling
参数,能够查看当前MySQL是否支持profile操作
select @@have_profiling
默认profiling是关闭的,可以通过set语句在 session/global级别开启profiling
直接在select 语句前加上关键字 explain / desc
如果使用的是联合索引,要遵循最左前缀法则。查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效)
假设user表存在联合索引(profession,age,status)
desc select * from user where profession = ‘软件’ and age = 31 and status=‘0’; 索引全部生效
desc select * from user where profession = ‘软件’ and age=31; status索引失效
desc select * from user where profession=‘软件’; age,status索引失效
desc select * from user where age=31 and status=‘0’;索引全部失效
>=
而不是>,<
在索引列上进行运算操作,索引将会失效
> select * from user where substring(phone,10,2)=‘15’;索引失效
字符串类型字段使用时,不加引号,索引将失效
> desc select * from user where phone=‘11111111111’;索引生效
> desc select * from user where phone=‘11111111111’;索引失效
如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引将失效
> select * from user where phone like ‘156%’;索引生效
select * from user where phone like ‘%6’; **索引失效 **
用 or 分割开的条件,必须两个条件中列都有索引,否则索引失效
如果MySQL 评估使用索引比全表更慢,则不使用索引
select * from user where phone >= ‘17799999999’;使用索引
select * from user where phone >=‘17700000000’;不使用索引
SQL提示,是优化数据库的一个重要手段,简单来说就是在SQL语句中加入一些人为的提示来达到优化操作的目的
desc select * from user use index(idx_user_pro) where profession = ‘软件工程’;
desc select * from user ignore index(idx_user_pro) where profession=‘软件工程’;
desc select * from user force index(idx_user_pro) where profession=‘软件工程’;
尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中能够全部找到),减少 select *
using index condition:查找使用了索引,但需回表查询数据
using where; using index:查询使用了索引,但需要的数据都在索引列中能找到,所以不需要回表查询数据
当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时浪费了大量的磁盘io,影响查询效率,此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,提高索引效率
create index 索引名 on 表名(字段名(n));
n为截取前面 n 个字符load
指令创建索引时,指定索引的排序方式:
create index idx_user_age_phone on user(age desc,phone desc);
一个常见的问题:limit 2000000,10,此时需要MySQL排序前 200010 记录,仅仅返回2000000-2000010的记录,其它的记录丢弃,查询排序的代价非常大
select s.* from stu s,(select id from stu order by id limit 2000000,10) a where s.id = a.id;
select count(*) from user;
服务层判断是否为null,不为null,计数累加
直接按行累加
count(*)
推荐不取值,服务层直接按行进行累加
更新的条件必须加索引,InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效 ,否则会从行锁升级为表锁
加锁后整个实力就处于只读状态,使用场景:全库的逻辑备份
开启全局锁:flush tables with read lock;
关闭全局锁:unlock tables;
表级锁,每次操作锁住整张表,锁定力度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB等存储引擎中
加锁:lock tables 表名… read/write
释放锁:unlock tables 或 关闭客户端