这个问题比较复杂,下面我直接列出一些可能的原因
一、客观问题
1、表损坏
不算常见的麻烦问题。引发表损坏的原因往往是:
① mysqld程序意外关闭、断电、强制关机
② mysql本身的bug或磁盘损坏
往往导致查询结果不全或损坏。可用check table语句检查。
2、锁表
数据库中有两种基本类型的锁:排他锁和共享锁。
若程序有bug导致出现“环路等待”,则引发死锁;共享锁遇到冲突升级为排他锁、行级锁升级为表级锁也可能导致死锁。
二、主观问题
1、请求了太多不需要的数据
select * 在多表关联时返回全部列;未使用limit等。
2、扫描了额外的记录
完美情况下,获取多少记录就扫描多少记录;然而这不总能实现,实际操作中扫描记录的数量可能远远大于要获取的记录。
可使用explain语句分析,然后合理使用索引,尽量覆盖查询。
或者重新设计查询语句
3、更改查询引擎
目前MySQL使用InnoDB作为默认查询引擎。
若使用MyISAM引擎,查询效率能够得到提升,但不支持事务、外键、行级锁。
查询时,InnoDB要同时缓存聚簇索引的索引块和数据块,而MyISAM只缓存索引块。
可将innodb_flush_log_at_trx_commit 置为0,事务提交时不写日志来提升InnoDB的速度
4、索引使用错误
正确使用索引,能够避免全表扫描,覆盖查询甚至不需要回表;
避免在查询语句where块中进行计算,或者使用<>,或者以%开头检索字符串,否则将无法使用索引。
删除无用的索引,维护索引需要一定的开销。
索引设计时,应注重覆盖索引和顺序检索带来的效率。
5、数据库表中字段过多
一般来说,MySQL的单表能承载千万级别的字段,过亿的数量应当分库分表。
6、join太多次
多半是表设计的问题,建议在应用层解决或采用反范式的设计。
7、列的类型选择错误
tinyint(1Byte)
smallint(2Byte)
mediumint(3Byte)
int(4Byte)
bigint(8Byte)
8、避免使用NULL字段
NULL字段很难查询优化;
NULL字段的索引需要额外空间;
NULL字段的复合索引无效;
原文:https://www.cnblogs.com/sh1296/p/10939861.html