Sql执行平时都很快但是偶尔就会很慢

Sql执行平时都很快但是偶尔就会很慢

记录一下在翻看MySQL技术文章的资料,觉得很不错就自己记录一下。大部分来源于网络。

SQL执行变慢的原因

一条Sql执行很慢,那是每次执行都慢还是偶尔慢,简单的总结一下:

一、针对偶尔慢的原因:

  1. 数据库在刷新脏页。
  2. 数据库的自然数连接占满了。
  3. 拿不到锁。

二、针对一直慢的原因

  1. Sql 索引没有用上或者选择错误的索引。
  2. 函数操作导致索引失效。
  3. 表过大,多表多库联合查询。

解释:

1、数据库在刷新脏页

	当我们输入一条新数据的时候,或者要更新一条数据的时候,我们知道数据库会在 内存 中把对应的字段值更新掉。但是更新之后,这些更新的字段并不是同步写入磁盘进行持久化操作,而是记录到redo log 日志里边,等待空闲的时候在写入磁盘,但是如果数据库一直在操作,redo log日志 存贮就达到上限,数据库就会全心把redo log 日志里的内容写入磁盘,而这个操作就导致我们的SQL查询变慢。

2、数据库连接的自然数满

	出现这种错误明显就是 mysql_connect 之后忘记 mysql_close;当大量的connect之后,就会出现Too many connections的错误,mysql默认的连接为100个,而什么情况下会出现这种错误呢?正常的mysql_connect 之后调用 mysql_close()关闭连接。但在连接错误时,会者mysql_real_query()出现错误退出时,可能忘mysql_close()

3、拿不到锁

	我们要执行的SQL,碰巧碰到别人也在用此条数据,就只能等待了。判断是否真的在等待锁,可以用

show processlist 命令来查询当前状态。

重要的是一直慢的原因

4、Sql 索引没有用上或者选择错误的索引。

	我们执行一条SQL,当这条SQL所用的where 条件的字段 没有添加索引就会导致数据库扫描全表。

	选择错误的索引则是因为MySQL会自己选择索引的基数,而选择这个基数的来源则是MySQL会对一些数据进行随机取样,如果碰巧等到MySQL取样的片区区分度很低,基数很小就会导致直接放弃使用索引,从而采取使用走全部扫描了。如果基数越大就查询越有优势。

基数:系统是通过索引的区分度来判断的,一个索引上的值越多,意味着出现相同数值的索引越少,意味着索引的区分度越高。我把区分度叫基数。

	关于使用错误的索引我们可以使用强制使用我们指定的方式来查询 FORCE INDEX (索引名)

Select * from A force index(a) where c < 1000 AND c >10000000

	也可以使用 SHOW INDEX FROM A 来查询索引基数是否和实际吻合,如果不符合的话我们可以从新来统计基数,可以用 ANALYZE TABLE A; 来进行重新统计分析。

5、函数操作导致索引失效

	select * from A where c -1 = 1000;   未使用索引。

	select * from A where c = 1000 +1;   使用索引。

6、数据太多又是夸表又是夸库的 肯定慢,但是可以优化到可以接受的程度上。

你可能感兴趣的:(MySQL,SQL,MySQL)