mysql数据库-索引-长期维护

###############    索引介绍    ##############

"""
1. 索引介绍
需求:
一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,
也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。
说起加速查询,就不得不提到索引了。

索引:
简单的说,相当于图书的目录,可以帮助用户快速的找到需要的内容.
在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。能够大大提高查询效率。
特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万倍.

本质:
索引本质:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,
同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。
"""

###############    索引方法    ##############

"""
2.索引方法
1. B+TREE 索引
B+树是一种经典的数据结构,由平衡树和二叉查找树结合产生,它是为磁盘或其它直接存取辅助设备而设计的一种平衡查找树,
在B+树中,所有的记录节点都是按键值大小顺序存放在同一层的叶节点中,叶节点间用指针相连,构成双向循环链表,
非叶节点(根节点、枝节点)只存放键值,不存放实际数据。
注意:通常其高度都在2~3层,查询时可以有效减少IO次数。

b+树的查找过程
如图所示,如果要查找数据项30,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,
在内存中用二分查找确定30在28和65之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,
通过磁盘块1的P2指针的磁盘地址把磁盘块由磁盘加载到内存,发生第二次IO,30在28和35之间,锁定当前磁盘块的P1指针,
通过指针加载磁盘块到内存,发生第三次IO,同时内存中做二分查找找到30,结束查询,总计三次IO。
真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,
如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。
强烈注意: 索引字段要尽量的小,磁盘块可以存储更多的索引.

2. HASH 索引
hash就是一种(key=>value)形式的键值对,允许多个key对应相同的value,
但不允许一个key对应多个value,为某一列或几列建立hash索引,就会利用这一列或几列的值通过一定的算法计算出一个hash值,对应一行或几行数据.
hash索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率.

3.HASH与BTREE比较:
hash类型的索引:查询单条快,范围查询慢
btree类型的索引:b+树,层数越多,数据量越大,范围查询和随机查询快(innodb默认索引类型)

不同的存储引擎支持的索引类型也不一样
InnoDB 支持事务,支持行级别锁定,支持 Btree、Hash 等索引,不支持Full-text 索引;
MyISAM 不支持事务,支持表级别锁定,支持 Btree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事务,支持表级别锁定,支持 Btree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 Btree、Full-text 等索引;
Archive 不支持事务,支持表级别锁定,不支持 Btree、Hash、Full-text 等索引;

"""

###############    索引类型    ##############

"""
3.索引类型
MySQL中常见索引有:
普通索引
唯一索引
主键索引
组合索引

1.普通索引
普通索引仅有一个功能:加速查询
#创建表同时添加name字段为普通索引
create table tb1(
   id int not null auto_increment primary key,
   name varchar(100) not null,
   index idx_name(name)
);
#单独为表指定普通索引
create index idx_name on tb1(name);
# 删除索引
drop index idx_name on tb1;
#查看索引
show index from tb1;

2.唯一索引
唯一索引有两个功能:加速查询 和 唯一约束(可含一个null 值)
# 创建表的时候创建
create table tb2(
  id int not null auto_increment primary key,
  name varchar(50) not null,
  age int not null,
  unique index idx_age (age)
)
# 单独创建
create unique index idx_age on tb2(age);

3.主键索引
 主键有两个功能:加速查询 和 唯一约束(不可含null)
 注意:一个表中最多只能有一个主键索引
# 创建表的时候穿件索引
#方式一:
create table tb3(
   id int not null auto_increment primary key,
   name varchar(50) not null,
   age int default 0
);
#方式二:
create table tb3(
   id int not null auto_increment,
   name varchar(50) not null,
   age int default 0 ,
   primary key(id)
);
# 单独添加索引
alter table tb3 add primary key(id);
# 删除索引
#方式一
alter table tb3 drop primary key;
#方式二:
#如果当前主键为自增主键,则不能直接删除.需要先修改自增属性,再删除
alter table tb3 modify id int ,drop primary key;

4.组合索引
组合索引是将n个列组合成一个索引
其应用场景为:频繁的同时使用n列来进行查询,如:where n1 = ‘alex‘ and n2 = 666。
# 创建表的时候穿件索引
create table tb4(
  id int not null ,
  name varchar(50) not null,
  age int not null,
  index idx_name_age (name,age)
)
# 单独添加索引
create index idx_name_age on tb4(name,age);

"""

###############   聚合索引和辅助索引   ##############

"""
4.聚合索引和辅助索引
数据库中的B+树索引可以分为聚集索引和辅助索引

聚集索引:InnoDB表 索引组织表,即表中数据按主键B+树存放,叶子节点直接存放整条数据,每张表只能有一个聚集索引。
1.当你定义一个主键时,InnnodDB存储引擎则把它当做聚集索引
2.如果你没有定义一个主键,则InnoDB定位到第一个唯一索引,且该索引的所有列值均飞空的,则将其当做聚集索引。
3如果表没有主键或合适的唯一索引INNODB会产生一个隐藏的行ID值6字节的行ID聚集索引,
补充:由于实际的数据页只能按照一颗B+树进行排序,因此每张表只能有一个聚集索引,聚集索引对于主键的排序和范围查找非常有利.

辅助索引:(也称非聚集索引)是指叶节点不包含行的全部数据,叶节点除了包含键值之外,还包含一个书签连接,通过该书签再去找相应的行数据
辅助索引叶节点存放的是主键值,获得主键值后,再从聚集索引中查找整行数据。举个例子,如果在一颗高度为3的辅助索引中查找数据,
首先从辅助索引中获得主键值(3次IO),接着从高度为3的聚集索引中查找以获得整行数据(3次IO),总共需6次IO。一个表上可以存在多个辅助索引。
总结二者区别:
相同的是:不管是聚集索引还是辅助索引,其内部都是B+树的形式,即高度是平衡的,叶子结点存放着所有的数据。
不同的是:聚集索引叶子结点存放的是一整行的信息,而辅助索引叶子结点存放的是单个索引列信息.

注意:
1.  mysql先去索引表里根据b+树的搜索原理很快搜索到id为4567890的数据,IO大大降低,因而速度明显提升
2. 我们可以去mysql的data目录下找到该表,可以看到添加索引后该表占用的硬盘空间多了 
3.如果使用没有添加索引的字段进行条件查询,速度依旧会很慢(如图:)

"""

###############    注意事项    ##############

"""
5.注意事项
数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。
即使建立索引,索引也不会生效

1. 避免使用select *
2. 其他数据库中使用count(1)或count(列) 代替 count(*),而mysql数据库中count(*)经过优化后,效率与前两种基本一样.
3. 创建表时尽量时 char 代替 varchar
4. 表的字段顺序固定长度的字段优先
5. 组合索引代替多个单列索引(经常使用多个条件查询时)
6. 使用连接(JOIN)来代替子查询(Sub-Queries)
7. 不要有超过4个以上的表连接(JOIN)
8. 优先执行那些能够大量减少结果的连接。
9. 连表时注意条件类型需一致
10.索引散列值不适合建索引,例:性别不适合

"""

###############    慢查询日志    ##############

"""
6,慢查询日志
将mysql服务器中影响数据库性能的相关SQL语句记录到日志文件,通过对这些特殊的SQL语句分析,改进以达到提高数据库性能的目的。

慢查询日志参数:
long_query_time     :  设定慢查询的阀值,超出设定值的SQL即被记录到慢查询日志,缺省值为10s
slow_query_log      :  指定是否开启慢查询日志
log_slow_queries    :  指定是否开启慢查询日志(该参数已经被slow_query_log取代,做兼容性保留)
slow_query_log_file :  指定慢日志文件存放位置,可以为空,系统会给一个缺省的文件host_name-slow.log
log_queries_not_using_indexes: 如果值设置为ON,则会记录所有没有利用索引的查询.

查看 MySQL慢日志信息
#.查询慢日志配置信息 :
show variables like ‘%query%‘;
#.修改配置信息
set global slow_query_log  = on;

查看不使用索引参数状态:
# 显示参数  
show variables like ‘%log_queries_not_using_indexes‘;
# 开启状态
set global log_queries_not_using_indexes  = on;

查看慢日志显示的方式
#查看慢日志记录的方式
show variables like ‘%log_output%‘;
#设置慢日志在文件和表中同时记录
set global log_output=‘FILE,TABLE‘;

测试慢查询日志
#查询时间超过10秒就会记录到慢查询日志中
select sleep(3) FROM user ;
#查看表中的日志
select * from mysql.slow_log;

"""

###############    数据库优化方案    ##############

1. 避免全表扫描,首先应考虑在 where 及 orderby 涉及的列上建立索引。
2. 避免在 where 子句中对字段进行 null 值判断,导致引擎放弃使用索引而进行全表扫描
3. 避免在 where 子句中使用 != 或>操作符,引擎将放弃使用索引而进行全表扫描。
4. 避免在 where 子句中使用or 来连接条件
5. 慎用in 和 not, 可以用 exists 代替 in
6. 慎用 like ‘XXX%‘,要提高效率,可以全文检索。
7. 应尽量避免在 where 子句中对字段进行表达式操作,如:
select id from t where num/2=100
应改为select id from t where num=100*2
8. 避免在where子句中对字段进行函数操作
select id from t where substring(name,1,3)=‘abc‘
改为:
select id from t where name like ‘abc%‘
9. 在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。(索引的最左前缀原则)
10. 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
11. 索引不是越多越好,索引可以提高select 的效率,同时也降低 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引。
12. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”
13. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
14. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
15. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
数据库中的数据在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大
16. 读写分离。通过数据库配置设置, mysql复制时,产生了多个数据副本(备库),为减少服务器压力,备库用于处理读操作,主库可同时处理读写。备库的复制是异步的,无法实时同步,读写分离的主要难点也在于备库上的脏数据。通常如果使用备库进行读,一般对数据的实时性要求不能太高。
17. 分库、分表。
18. 利用缓存存储经常被查询的数据。利用redis、memcache

###############    结束线    ##############

原文地址:https://www.cnblogs.com/andy0816/p/12275391.html

时间: 2024-10-07 01:19:42

mysql数据库-索引-长期维护的相关文章

mysql数据库-进阶-长期维护

###############    视图    ############## """ 1.视图 视图:是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据 视图有如下特点; 1. 视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系. 2. 视图是由基本表(实表)产生的表(虚表). 3. 视图的建立和删除不影响基本表. 4. 对视图内容的更新(添加.删除和修改)直接影响基本表. 5. 当视图来自多个基本表时,不允许添加和删除数据. 1.

mysql数据库-基础--长期维护

###############    数据库    ############## 主要是通过这个学习到什么? 1,库的操作 2,表的操作,包括查询,多表查询,子查询 3,视图,事务,索引,锁, ###############    数据库操作    ############## """ 数据库操作: 1.创建数据库 #创建一个名字为 db_name 的数据库,并指定当前库的编码集为utf8 CREATE DATABASE db_name charset utf8; 2.查看数

php教程:MySql数据库索引原理

PHP教程有好几天都没有给大家带来关于PHP方面的知识啦,今天补上啊!本文这要讲述的是:MySql数据库索引原理,希望能对大家带来帮助! 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中InnoDB数据存储引擎中索引的架构实现讨论聚集索引.非聚集索引及覆盖索引等话题. 第三部分讨论MySQL中高性能使用索引的策略. 一.数据结构及算法理论 Innodb存储引擎实现索引的数据结构是B+树,下面介绍几种数据结构,一步步阐述为什么要使用B+树 1

MySQL数据库索引常见问题

笔者看过很多数据库相关方面的面试题,但大多数答案都不太准确,因此决定在自己blog进行一个总结. Q1:数据库有哪些索引?优缺点是什么? 1.B树索引:大多数数据库采用的索引(innoDB采用的是b+树).能够加快访问数据的速度,尤其是范围数据的查找非常快.缺点是只能从索引的最左列开始查找,也不能跳过索引中的列,如果查询中有某个列用到了范围查询,则右边所有列都无法使用索引优化查找. 2.哈希索引:基于哈希表实现.在MySQL中,只有Memory引擎显式的支持哈希搜索.哈希查找的速度非常快,但哈希

Mysql数据库索引

索引(Index)是帮助mysql高效获取数据的数据结构.对于高性能非常关键. 索引的重要性主要体现在数据量非常大的时候.规模小,负载轻的数据库即使没有索引也可以获到好的查询效果 例如: 1 mysql>select first_name from actor where actor_id=5; 改索引列位于actor_id列,因此mysql会使用索引找到actor_id为5的行. 索引有很多种类型,各自有各自的特点.索引实在存储引擎层实现的,而不是服务器层. (1).B-Tree索引 谈论引擎

第二百八十八节,MySQL数据库-索引

MySQL数据库-索引 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可. 如果没有创建索引查找数据时,是全表扫描的,也就是向查字典一样没有目录,靠一页一页的翻到目标数据位置,这样如果数据量大会相当耗时, 索引就是快速帮助用户找到目标数据,节省时间 索引简介 索引是以B+tree方式的树形结构存放数据的 详情,可以网上搜索一下B+tree MySQL中常见索引有: 普通索引 唯一索引 主键索引 组合索

MySQL数据库索引的4大类型以及相关的索引创建

以下的文章主要介绍的是MySQL数据库索引类型,其中包括普通索引,唯一索引,主键索引与主键索引,以及对这些索引的实际应用或是创建有一个详细介绍,以下就是文章的主要内容描述. (1)普通索引 这是最基本的MySQL数据库索引,它没有任何限制.它有以下几种创建方式: 创建索引 CREATE INDEX indexName ON mytable(username(length)); 如果是CHAR,VARCHAR类型,length可以小于字段实际长度:如果是BLOB和TEXT类型,必须指定 lengt

如何正确合理的建立MYSQL数据库索引

如何正确合理的建立MYSQL数据库索引 索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable表: CREATE TABLE mytable( IDINTNOT NULL, username VARCHAR(16) NOT NULL ); 我们随机向里面插入了10000条记录,其中有一条:5555, admin. 在查找username="admin

MySQL数据库------索引

MySQL数据库------索引 一.索引的介绍 数据库中专门用于帮助用户快速查找数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取. 二 .索引的作用 约束和加速查找 三.常见的几种索引: 普通索引,唯一索引,主键索引(这几个都是单列) 联合索引(多列),比如:联合主键索引.联合唯一索引.联合普通索引 无索引和有索引的区别以及建立索引的目的 无索引: 从前往后一条一条查询有索引:创建索引的本质,就是创建额外的文件(某种格式存储,查询的时候,先