mysql设置id值为索引值_MySQL 索引
一、索引作用
提供了类似于书中目录的作用,目的是为了优化查询
(一)、索引种类
1、B树索引(Balance Tree)
作用
Btree的设计理念,就是让查询能够快速锁定范围,特别适合于范围查询。
种类
B树
B+树 相邻叶子节点上有双向指针
B*树 相邻非叶子节点上有双向指针
构建过程
1、数据排序
2、排序后的结构,均匀的落在各个leaf节点上
3、下层提取leaf节点的范围+指针构成No-leaf节点
5、下层提取No-leaf节点范围+指针构成root节点
2、Hash索引
3、R树
4、Full text
5、GIS
(二)、BTREE在MySQL中的应用
聚簇索引
1. 前提
a. 建表时有主键,主键选择为聚簇索引
b.没有主键,选唯一
c.都没有,生成6字节隐藏索引
建议:使用数字自增列创建为主键
2. 功能
a录入数据时,按照聚簇索引组织存储数据, 在磁盘上有序存储数据行
在一个区中,数据行从逻辑到物理都是有序的。
b. 加速查询
where id条件
辅助索引回表查询
3. 构建过程
a.Leaf节点:整表数据行所在的数据页
b. No-Leaf节点: 下层叶子节点ID范围+指针
c. ROOT节点:下层No-Leaf节点ID范围+指针
辅助索引
1. 前提
需要按照查询条件创建合理的辅助索引
2. 功能
加速查询:利用辅助索引作为查询条件是才能加速
3. 构建过程
a.Leaf节点:索引键值+主键ID,根据索引键值排序后生成
b. No-Leaf节点: 下层叶子节点键值范围+指针
c. ROOT节点:下层No-Leaf节点键值范围+指针
回表
查询完辅助索引之后,得到主键值,回聚簇索引树查询。
联合索引
联合索引应用要满足最左原则
1、联合索引构建:idx(a,b,c)
叶子结点
1. 提取a,b,c+id
2. 按照a,b,c进行排序
3. 生成叶子节点
枝节点
1.提取最左列的范围+指针
根节点
提取枝节点范围+指针
2、联合索引建立规范
a. 建立联合索引时,选择重复值最少的列作为最左列。
b. 使用联合索引时,查询条件中,必须包含最左列,才有可能应用到联合索引
3、索引应用注意问题
回表
影响:
IO量增多
IO次数增多(IOPS)
随机IO增多
减少方法:
使用联合索引联合索引
精细化查询条件
尽量使用唯一值多的列作为查询条件,并建立索引
优化器:MRR(Multi-Range-Read)
查看所有优化器
select @@optimizer_switch;
设置优化器状态
set global optimizer_switch='mrr=on';
功能:
1. 辅助索引查找后得到ID值,进行自动排序
2. 一次性回表,很有可能受到B+TREE中的双向指针的优化查找。
索引树高度
1、数据行
分表、归档、分布式
2、索引列值长度
前缀索引(字符串列)
3、主键过长
主键最好使用自增数字列
4、数据类型选择
合适的、简短的
(三)、索引管理操作
1、查询索引
①、desc 表名称;
例:desc t1;
PK(PRI) --> 主键(聚簇索引)
MUL --> 辅助索引
UK --> 唯一索引
②、show index from t1;
2、添加索引
alter table 表名 add index 索引名(列);
例:alter table t100w add index idx_k2(k2);
添加联合索引
alter table 表名 add index 索引名(列1名,列2名);
例:alter table t100w add index idx_k1_num(k1,num);
添加前缀索引
alter table 表名 add index 索引名(列名(取值位数));
例:alter table city add index idx_n(name(5));
判断前缀长度多少合适:
select count(distinct(left(列名,取值长度))) from city 表名;
select count(distinct(left(name,5))) from city ;
删除索引
alter table 表名 drop index 索引名;
(四)、执行计划
1、获取SQL语句执行计划
desc SQL
explain SQL
2、分析
select_type:查询类型
table:此次查询访问的表
partitions:分区表
type:索引查询的类型
ALL:没有使用到索引,全表扫描
查询条件没建立索引
有索引不走
index:全索引扫描
range:索引范围扫描
> < >= <= betweed and like
in or
条件列值重复值少
改写union all
重复值多,没必要改写
ref:辅助索引等值查询
eq_ref:多表连接查询中,非驱动表的连接条件是主键或唯一键时
const(system):主键或唯一键等值查询
NULL
possible_keys:可能会应用的索引
key:最终选择的索引
key_len:
索引覆盖长度,主要是用来判断联合索引应用长度
列的key_len长度,按照每列的最大预留长度来做的计算
ref
rows:需要扫描的行数
filtered:过滤
extra:额外信息
using filesort:额外的排序操作
(五)、应用场景
1、数据库慢
①、应急性的慢
show full processlist; ----> 找到慢语句 ----> explain SQL ---> 优化索引、改写语句
查看正在运行命令 查看执行计划
②、间歇性慢
slowlog ----> 慢语句 ---> explain SQL ---> 优化索引、改写语句
(六)、索引应用规范
1、建立索引的原则(DBA运维规范)
说明
为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索
2、索引创建原则
①、建表时一定要有主键,一般是个无关自增列数字列,可以降低索引树高度
②、选择唯一键索引
唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录
③、尽量使用前缀来索引
如果索引字段的值很长,最好使用值的前缀来索引
④、限制索引的数目
3、索引的数目不是越多越好索引条目过多所产生的问题
(1) 每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。
(2) 修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
(3) 优化器的负担会很重,有可能会影响到优化器的选择.
删除不再使用或者很少使用的索引(percona toolkit)
大表加索引,要在业务不繁忙期间操作
尽量少在经常更新值的列上建索引
4、不走索引的情况(开发规范)
①、没有查询条件,或者查询条件没有建立索引
②、查询结果集是原表中的大部分数据,应该是15-25%以上。
③、索引本身失效,统计信息不真实(过旧)
手动更新统计信息:
ANALYZE TABLE 库名.表名;
例:ANALYZE TABLE world.city;
④、查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等)
⑤、隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误.
<> ,not in 不走索引(辅助索引)
like "%_" 百分号在最前面不走
(七)优化器针对索引的算法
1、自优化能力
①、MySQL索引的自优化-AHI(自适应HASH索引)
MySQL的InnoDB引擎,我们能够手动创建的只有Btree
AHI作用:
自动评估"热"的内存索引page,生成HASH索引表。
帮助InnoDB快速读取索引页。加快索引读取的效果。
相当与索引的索引
②、MySQL索引的自优化-Change buffer
比如insert,update,delete 数据。
对于聚簇索引会立即更新。
对于辅助索引,不是实时更新的。
在InnoDB 内存结构中,加入了insert buffer(会话),现在版本叫change buffer。
Change buffer 功能是临时缓冲辅助索引需要的数据更新。
当我们需要查询新insert 的数据,会在内存中进行merge(合并)操作,此时辅助索引就是最新的。
2、可选的优化器算法-索引
①、优化器算法查询
select @@optimizer_switch;
index_merge=on,
index_merge_union=on,
index_merge_sort_union=on,
index_merge_intersection=on,
engine_condition_pushdown=on,
index_condition_pushdown=on,ICP,索引下推
作用:
SQL层做完过滤后,只能用a,b的部分辅助索引,
将c列条件的过滤下推到engine层,进行再次过滤。
排除无用的数据页。
最终去磁盘上拿数据页。大大减少无用IO的访问。
mrr=on,mrr_cost_based=on,MRR : Multi Range Read
作用: 减少回表。减少随机IO。
开关方法:
set global optimizer_switch='mrr=on,mrr_cost_based=off';
SNLJ 普通嵌套循环连接伪代码:
for each row in A matching range {
block
for each row in B {
A.xx = B.yy ,send to client
}
}
block_nested_loop=on,作用
在 A和B关联条件匹配时,不再一次一次进行循环。采用块循环连接。
A表中需要关联的数据,现在join buffer缓冲
而是采用一次性将驱动表的关联值和非驱动表匹配.一次性返回结果
主要优化了CPU消耗,减少了一部分IO消耗。
触发条件:非驱动表的连接条件有辅助索引
batched_key_access=off,作用,使用来优化非驱动表的关联列有辅助索引。
BNL+ MRR的功能。
开启方式:
mysql> set global optimizer_switch='mrr=on,mrr_cost_based=off';
mysql> set global optimizer_switch='batched_key_access=on';
重新登陆生效
materialization=on,
semijoin=on,
loosescan=on,
firstmatch=on,
duplicateweedout=on,
subquery_materialization_cost_based=on,
use_index_extensions=on,
condition_fanout_filter=on,
derived_merge=on
②、修改优化器算法
方法一:配置文件中修改
PS:重启生效
vim my.cnf
optimizer_switch='batched_key_access=on'
#优化器='算法=开/关'
方法二:命令行中修改
PS:重新登录生效
set global optimizer_switch='batched_key_access=on';
set global optimizer_switch='算法=开/关';
方法三:执行命令时修改(hints)
SELECT /*+ NO_RANGE_OPTIMIZATION(t3 PRIMARY, f2_idx) */ f1
FROM t3 WHERE f1 > 30 AND f1 < 33;
SELECT /*+ BKA(t1) NO_BKA(t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
SELECT /*+ NO_ICP(t1, t2) */ * FROM t1 INNER JOIN t2 WHERE ...;
SELECT /*+ SEMIJOIN(FIRSTMATCH, LOOSESCAN) */ * FROM t1 ...;
EXPLAIN SELECT /*+ NO_ICP(t1) */ * FROM t1 WHERE ...;
3、8.0 版本索引的新特性
①、不可见索引。invisable/visable index
针对优化器不可见。但是索引还在磁盘存在,还会自动维护。
对于索引维护时,不确定索引是否还有用。这时可以临时设定为invisable。
②、倒序索引
select * from t1 where c = order by a ASC , b desc ;
idx(c,a, b desc )
(八)、优化器默认优化规则
1、选择驱动表
默认选择方式(非驱动表):
按照on的条件列,是否有索引,索引的类型选择。
1. 在on条件中,优化器优先选择有索引的列为非驱动表。
2. 如果两个列都有索引,优化器会按照执行的代价去选择驱动表和非驱动表。
2、关于驱动表选择的优化思路
理论支撑:
mysql> desc select * from city join country on city.countrycode=country.code ;
mysql> desc select * from city left join country on city.countrycode=country.code ;
查询语句执行代价:
mysql> desc format=json select * from city join country on city.countrycode=country.code ;
mysql> desc format=json select * from city left join country on city.countrycode=country.code ;
实践检验: (可以通过 left join 强制驱动表)
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='world' --query="select * from city left join country on city.countrycode=country.code ;" engine=innodb --number-of-queries=2000 -uroot -p123 -verbose
默认驱动表
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='world' --query="select * from city join country on city.countrycode=country.code ;" engine=innodb --number-of-queries=2000 -uroot -p123 -verbose
(九)、多表连接优化总结
1、驱动表选择
①、让优化器自己决定
(1). 在on条件中,优化器优先选择有索引的列为非驱动表。
(2). 如果两个列都有索引,优化器会按照执行的代价去选择驱动表和非驱动表。
②、自主选择
left join强制驱动表
查询语句执行代价:
mysql> desc format=json select * from city join country on city.countrycode=country.code ;
mysql> desc format=json select * from city left join country on city.countrycode=country.code ;
关于驱动表选择的优化思路
理论支撑:
mysql> desc select * from city join country on city.countrycode=country.code ;
mysql> desc select * from city left join country on city.countrycode=country.code ;
实践检验: (可以通过 left join 强制驱动表)
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='world' --query="select * from city left join country on city.countrycode=country.code ;" engine=innodb --number-of-queries=2000 -uroot -p123 -verbose
默认驱动表
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='world' --query="select * from city join country on city.countrycode=country.code ;" engine=innodb --number-of-queries=2000 -uroot -p123 -verbose
不管是优化单表或多表,重点是在于索引和语句本身优化。
mysql设置id值为索引值_MySQL 索引相关推荐
- MySQL设置当前时间为默认值的方法
方法一.是用alert table语句: 复制代码代码如下: use test_db1; create table test_ta1( id mediumint(8) unsigned not n ...
- mysql设置主键初始默认值
mysql设置主键默认开始值 在Navicat 中输入一下命令(默认以1000开始) List itemalter table resource AUTO_INCREMENT=1000; 如果报错输入 ...
- mysql设置id重新从1开始自增
mysql设置id重新从1开始自增 在测试程序时,通常会把id变得非常大,而且也会导致id不连续,我们可以让id从1开始重新自增 首先我们应该先清空表中数据 新建查询,然后执行一条 sql语句,再插入 ...
- mysql索和使用引的创建_MySQL索引的创建与使用
索引有很多,且按不同的分类方式,又有很多种分类.不同的数据库,对索引的支持情况也不尽相同. 声明:本人主要简单示例MySQL中的单列索引.组合索引的创建与使用. 索引的创建 建表时创建 CREATE ...
- mysql 索引 原理_MySQL索引实现原理分析
目前大部分数据库系统及文件系统都采用B-Tree(B树)或其变种B+Tree(B+树)作为索引结构.B+Tree是数据库系统实现索引的首选数据结构.在MySQL中,索引属于存储引擎级别的概念,不同存储 ...
- mysql查询索引位置_mysql索引在什么位置
mysql索引的位置在[数据库安装目录\data\databasename].索引是存储引擎用于快速找到记录的一种数据结构.索引对于良好的性能非常关键. MySQL中索引的简介 (视频教程推荐:mys ...
- MySQL建立的索引看_MYSQL索引问题:索引在查询中如何使用?看了很多资料都只说索引的建立。是否建立了就不用再理会?...
# 有这样一个表 P mysql> create table P (id int primary key, name varchar(10) not null, sex varchar(1), ...
- mysql查询id为5的数据类型_MySql学习05---数据类型
MySql支持多种数据类型,主要有数值类型.日期/时间类型和字符串类型. 数值数据类型:包括整数类型TINYINT.SMALLINT.MEDIUMINT.INT.BIGINT.浮点小数数据类型FLOA ...
- mysql 索引 二_MySql索引(二)
所有MySQL列类型可以被索引.根据存储引擎定义每个表的最大索引数和最大索引长度. 所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节.大多数存储引擎有更高的限制. 索引的存储类型目前只 ...
最新文章
- Python Numpy 教程(使用 Jupyter 和 Colab)
- ubuntu虚拟机卡住开机_虚拟机Ubuntu开机问题及解决方法
- S5PV210裸机之Nandflash
- thinkphp漏洞_【组件攻击链】ThinkCMF 高危漏洞分析与利用
- 文本框换行_word的段落标记与换行,你真的知道么?
- 5G时代下的移动边缘计算(MEC)探索系列之四
- 什么是 CNC?什么是电脑锣?学 CNC主要学什么?
- ESP32黑客帝国数字雨动画,矩阵它来了,ESP32+ST7789V液晶屏Arduino
- oracle sql 实现三张表左连接查询
- 2021最后一个月了,你找到带回家的那个她了吗?送你999朵玫瑰。
- Scala基础:类和构造器
- SQL连接MYSQL出现对象名无效_SQL数据库时提示对象名'XXX' 无效
- 基于电商直播SDK快速实现一个淘宝直播APP【内附源码】
- 人工智能+大数据+云计算
- 数据库的事务ACID特性以及MySQL如何保持事物特性
- 计算机图形学中的常用模型
- 软件安全建设【学习笔记】
- 曼谷梦幻世界主题公园有什么好玩的
- 【Excel--高级筛选】学习总结
- 运维(1) Jenkinsfile+Dockerfile+Nginx实现前端Vue自动化部署