文章目录
- 1 偶尔很慢
- 1.1 数据库在刷新脏页
- 1.2 执行的时候遇到锁
- 2 一直很慢
- 2.1 没有使用到索引
- 2.1.1 `字段`没有索引
- 2.1.2 字段有索引,但是`sql语句`没有使用
- 2.1.3 `函数操作`导致没有用上索引
- 2.2 数据库选错了索引
面试的时候就是抻,说得越详细越好。
所以得分类讨论。
1 偶尔很慢
1.1 数据库在刷新脏页
往数据库更新数据(增、删、改)的时候,数据库会在内存
中把对应的记录更新,但是更新之后,并不会马上同步持久化到磁盘
中去,而是把这些更新的记录写入到redo log
日记中去,等到空闲时,再通过日记把数据同步到磁盘中
去。
1.2 执行的时候遇到锁
表
被加锁,或者行
被加锁。
可以用show processlist
命令查看是否在等待锁。
2 一直很慢
2.1 没有使用到索引
表结构如下:
mysql> CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
2.1.1 字段
没有索引
此时字段c
没有索引,假设要查找如下的记录,则需要全表扫描。
select * from t where 100 <c and c < 100000;
2.1.2 字段有索引,但是sql语句
没有使用
假设字段c
现在已经加上了索引,但是使用如下语句查询,系统仍然会全表扫描。
select * from t where c - 1 = 1000;
正确的语句操作应该是:
select * from t where c = 1000 + 1;
2.1.3 函数操作
导致没有用上索引
同上所示,对字段进行了函数操作,导致没有用上索引
select * from t where pow(c,2) = 1000;
2.2 数据库选错了索引
例如,进行如下记录的查找,字段c有索引。
- 补充一下。
主键索引
,存放的值是整行字段
的数据。非主键索引
,存放的是主键字段
的值。
select * from t where 100 < c and c < 100000;
因为字段c不是主键,如果走c字段的索引的话,最后会查询到对应主键的值,然后根据主键的值,走主键索引,查询到整行数据返回。
即,就算字段c上有索引,系统也并不一定会走c这个字段上的索引,而是有可能扫描全表,找出符合要求的字段。