(一) MySQL性能下降
也许在现在大家的数据库表存储数据还停留在几千条, 几万条的样子, 所以编写一般的正确的SQL语句在性能上完全看不出有什么瑕疵, 而当数据到达了三百万条左右及以上时, 类似于 "select * from table where condition"的操作会暴露出性能下降的问题, 下面首先来讨论一下MySQL性能下降的原因 :
执行时间长、等待时间长:
1. 查询语句写的烂:各种连接,各种子查询导致不能用索引,或者没有建立索引。
2. 索引失效:建了索引没用上。
3. 关联查询太多join(设计缺陷或不得已的需求)
4. 服务器调优及各个参数设置(缓冲、线程数等)
(二) 索引[重要!]
1. 首先我们先来认识索引是什么?
索引(Index)是一种帮助MySQL高效获取数据的数据结构
索引的本质: 它是一种数据结构, 不是数据!
2. 索引的目的
提高查询效率, 可以类比到字典上, 索引用于"排序" 和 "快速查找" !
例子(有助于你理解索引的作用) :
如果要查"mysql"单词, 我们肯定要定位到m字母, 继续往下找到y字母, 再找剩下的mysql
如果没有索引,那么你可能需要a----z,一个个查找.
如果建立了索引, 可以快速直接定位到字母m, y, s, q, l这几个字母.
3. 索引的优势和劣势
3.1 优势:
1. 大学图书馆建立书目索引, 提高数据检索的效率, 降低数据库的IO成本(IO)
2. 通过索引列对数据进行排序,降低数据排序的成本, 降低了CPU的消耗.(运算CPU)
3.2 劣势:
1. 实际上索引也是一张表, 该表保存了主键和索引字段, 并指向实体表的记录, 所以索引也是要占空间的
2. 虽然索引大大提高了查询速度,同时却会降低更新表的速度, 例如对表进行INSERT, UPDATE和DELETE. 因为更新表时, MySQL不仅要保存数据, 还要保存一下索引文件每次更新添加了索引列的字段, 都会调整因为更新所带来的键值变化后的索引信息
3. 索引只是提高效率的一个因素, 如果你的MySQL有大数据量的表, 就需要花时间研究建立最优秀的索引, 或优化查询.
4. 索引分类和建索引命令语句
4.1 索引可分为以下两种类型:
1. 单值索引:
即一个索引只包含单个列, 一个表可以有多个单列索引.
一张表最多的索引不要超过五个
例子:
select * from user where name = '';
create index idx_user_name on user(name);
2. 复合索引:
即一个索引包含多个列
例子:
select * from user where name = '' and email='';
create index idx_user_nameEmail on user(name, email);
3. 唯一索引:
索引列的值必须唯一,但允许有空值.(银行数据表里的银行卡号)
4. 基本语法:
创建: CREATE [UNIQUE] INDEX indexName ON myTbale(columnName(length));
ALTER myTable ADD [UNIQUE] INDEX [indexName] on (columnName(length))
删除: DROP INDEX [indexName] on myTable;
查看: SHOW INDEX FROM table_name\G
使用ALTER命令:
1.ALTER TABLE tbl_name ADD PRIMARY KEY(column_list);
该语句添加一个主键, 这意味着索引值必须是唯一的, 且不能为NULL
2.ALTER TABLE tbl_name ADD UNIQUE index_name(column_list)
该语句创建唯一索引(除了NULL外, NULL可能会出现多次)
3.ALTER TABLE tbl_name ADD INDEX index_name(column_list);
该语句创建普通索引, 索引值可出现多次.
4. ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list);
该语句指定了索引为FULLTEXT, 用于全文索引
构造索引的索引名格式:idx_表名_字段名 on 表名(字段名);
5. MySQL索引结构
主攻BTree索引,知道还有Hash索引, full-text全文索引, R-Tree索引
BTree检索原理
6. 哪些情况需要创建索引?
1. 主键自动建立唯一索引.
2. 频繁作为查询条件的字段应该创建索引
3. 查询中与其它表关联的字段, 外键关系建立索引
4. 频繁更新的字段不适合创建索引
5. Where条件里用不到的字段不创建索引
6. 单键/组合索引的选择问题, who?(在高并发下倾向于创建组合索引)
7. 查询中排序的字段, 排序字段若通过索引去访问将大大提高排序速度(order by 排序字段)
8. 查询中统计或分组字段(group by 分组字段)
7. 哪些情况不适合创建索引?
1. 表记录太少(300万条以上数据,MySQL性能开始下降)
2. 经常在增删改的表(因为提高了查询速度, 同时却会降低更新表的速度, 如对表进行INSERT, UPDATE, 和DELETE.因为更新表时, MySQL不仅要保存数据, 还要保存一下索引文件)
3. 注意, 如果某个数据列包含许多重复的内容, 为它建立索引就没有太大的实际效果.(男/女 中国国籍)
例子: 假如一个表有10万行记录, 有一个字段A只有True和False两种值, 且每个值得分布概率大约为50%, 那么对这种表A字段建立索引一般不会提高数据库的查询速度.
索引的选择性是指索引列中不同值得数目与表中记录数的比. 如果一个表中有2000条记录, 表索引列有1980个不同的值, 那么这个索引的选择性就是1980/2000 = 0.99. 一个索引的选择性越接近于1, 这个索引的效率就越高.
今天就记录这么多吧, 主要是让大家理解MySQL性能下降的原因还有索引相关的基础知识, 希望能与你们一起进步!如有疑问可以留言, 我很乐意与你们交流!