平时我们要优化 mysql 查询效率的时候,最常见的就是给表加上合适的索引了,那今天就来聊聊为什么加了索引就快了呢。...mysql 索引其实就是一颗 B+ 树。...select * from t where m > 1000 and m < 3000; 再来看另一条 sql 语句,这个语句可以使用索引 k,所以该查询会先到二级索引 k 这个 B+ 树上,快速找到满足要求的叶子节点...select * from t where k > 3 and k < 6; 这就是为什么加了索引后,mysql 查询会变快的原因了,其实刚提到的这个回表过程还可以再优化的,就是利用覆盖索引,后面的文章我们再详细说...推荐文章: mysql索引为啥要选择B+树 (上) python画哆啦A梦和大雄
mysql添加索引的方法:可以通过【create table】语句来添加,如【CONSTRAINT PRIMARY KEY | INDEX [] [] 】,表示创建一般索引。...在mysql中可以在创建表(CREATE TABLE)的同时创建索引;也可以在创建表后创建索引,使用CREATE INDEX语句或ALTER TABLE 语句。...(视频教程推荐:mysql视频教程) 1、使用CREATE INDEX语句 可以使用专门用于创建索引的 CREATE INDEX 语句在一个已有的表上创建索引,但该语句不能创建主键。...mysql> CREATE TABLE tb_stu_info -> ( -> id INT NOT NULL, -> name CHAR(45) DEFAULT NULL, -> dept_id INT...示例:mysql> SHOW CREATE TABLE tb_stu_info\G *************************** 1. row ************************
1.添加PRIMARY KEY(主键索引) mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) mysql...>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 3.添加INDEX(普通索引) mysql>ALTER TABLE `table_name` ADD...INDEX index_name ( `column` ) 4.添加FULLTEXT(全文索引) mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column...` ) 5.添加多列索引 mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
以索引创建为例: image.png 从上文可见,当我们创建、删除或重命名索引时,会采用“in place”的模式。...此外,如果 Online DDL 操作失败,其回滚操作可能会造成较高的成本。长时间运行的 Online DDL 操作也可能导致主从同步的延迟。...创建索引数据字典。 对原表加共享 MDL 锁,阻止对原表的写操作,只允许查询操作。 根据聚集索引的顺序,查询表中的数据,并提取所需的索引列数据。将提取的索引数据进行排序,并插入到新的索引页中。...DEFAULT:如果不指定 ALGORITHM,MySQL 会自行选择默认算法。它优先考虑 INSTANT,其次是 INPLACE,然后是 COPY。...加 EXCLUSIVE-MDL 锁,阻止读写操作。 根据 ALTER 类型,确定执行方式(copy/online-rebuild/online-norebuild)。
MySQL是支持前缀索引的,前缀索引的优势就是占用的空间小,这同时带来的损失是,可能会增加额外的记录扫描次数。...,那这些语句就只能做全表扫描 MySQL 是支持前缀索引的,可以定义字符串的一部分作为索引。...其中email(6)这个索引结构中每个邮箱字段只取前6个字节,占用的空间会比较小,这是使用前缀索引的优势,但是带来的损失可能会增加额外的记录扫描次数 看看下面这个语句 select id,name,email...有以下2中方式 就是使用倒序存储,比如身份证倒序,查询的时候再用函数转一下 以及使用hash字段,在表上创建一个整数字段,来保存身份证的校验码,同时在这个字段上加索引 这两种方式对比区别 从占用的额外空间来看...而倒序存储方式毕竟还是用的前缀索引的方式,也就是说还是会增加扫描行数。 我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
提到在线加索引都是商业数据库的功能,例如SQL SERVER 在线加索引就是你花钱买的版本也必须是企业版, 标准版都不能在线加索引。...POSTGRESQL 支持在线加索引的功能,在本文撰写期间MYSQL 是不支持 online add index 对于几千万的大表建立索引还是要使用工具,并且8.0 使用gh ost 是有我问题,所以对于大表加索引并且是...这样的方式对于索引的工作就比较复杂了,因为MVCC的原因 INDEX 也会产生多个版本,并且指向不同版本的数据,同时如果要清理这些DEAD TUPLE 需要清理这些dead index, 不及时清理这些索引...,而这些变化并没有被记录到新的索引中. 5 因为索引建立是基于第一次SNAPSHOT,所以建立在线索引的活动会再次发起,这次还是要等待所有的事务都结束后,开始建立SNAPSHOT,再次对表进行扫描将实际表中的数据的变化与索引的数据进行同步和改变...所以在线加索引最怕的是大事务,如果此时有大事务在工作,那么在线加索引等待的时间就是你大事务的时间,所以即使是在线加索引,也需要在业务低峰期进行,这样等待的时间会小,并且遇到的麻烦也少.
就跟卡bug一样,比如说你去面试,面试官问你:MySQL为什么会死锁;你告诉面试官:你录用我我就告诉你,面试官说:你告诉我我就录用你,然后你两就一直这么你问我我问你,这就是死锁。...: 3️⃣ 死锁的底层原理分析 其实有了昨天的知识储备,了解了查询的时候的加锁情况,我们其实不难分析出为什么会死锁: select * from team where position_no = 6 for...update语句属于非唯一索引的等值查询,会加上(6,+∞]的临键锁 select * from team where position_no = 7 for update语句属于非唯一索引的等值查询...…… 总结 今天的文章只是带大家简单走了一遍MySQL的死锁情况,关于为什么会死锁,讲完昨天的文章,也就是对查询时的加锁情况的讲解,其实来分析这个死锁的情况并不是一件难事,最后也介绍了从数据库层面和业务层面如何去防止...MySQL出现死锁的情况。
,大于49时就走PRIMARY主键索引。...report_product_sales_data_hq_code_orgz_id_index PRIMARY 4 NULL 7624 Using where 开启优化器跟踪查看MySQL...{ "reconsidering_access_paths_for_index_ordering": { //到了order by id这边时,MySQL...由于自身的优化器选择,为了避免某些排序的消耗,可能会走非预期的PRIMARY主键索引; 对于数据量比较大,而且执行量很高的分页sql,尽可能将所有的查询字段包括在索引中,同时使用索引来消除排序; 多用explain...查看是否使用到了最优索引; 利用optimizer trace查看优化器执行过程; 观察mysql的slow_query_log,及时做排查优化。
,大于49时就走PRIMARY主键索引。...report_product_sales_data_hq_code_orgz_id_index PRIMARY 4 NULL 7624 Using where 开启优化器跟踪查看MySQL...由于自身的优化器选择,为了避免某些排序的消耗,可能会走非预期的PRIMARY主键索引; order by 和 limit 结合使用,如果where 字段,order by字段都是索引,那么有limit索引会使用...order by字段所在的索引,没有limit会使用where 条件的索引; 对于数据量比较大,而且执行量很高的分页sql,尽可能将所有的查询字段包括在索引中,同时使用索引来消除排序; 多用explain...查看是否使用到了最优索引; 利用optimizer trace查看优化器执行过程; 观察mysql的slow_query_log,及时做排查优化。
(3) 唯一性约束强制在指定的列上创建一个唯一性索引。在默认情况下,创建唯一性的非聚簇索引,但是,也可以指定所创建的索引是聚簇索引。...死锁 insert … on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后...mysql执行完duplicate后的update操作, 然后对该记录加上X(排他锁),最后进行update写入。...id的改变;insert … on duplicate key update在遇到重复行时,会直接更新原有的行,具体更新哪些字段怎么更新,取决于update后的语句。...参考 Mysql中unique与primary约束的区别分析(转) MySQL避免插入重复记录:唯一性约束 MySQL优化–INSERT ON DUPLICATE UPDATE死锁 ---- 我是蜗牛
那么,MySQL 是怎样得到索引的基数的呢?这里,我给你简单介绍一下 MySQL 采样统计的方法。为什么要采样统计呢?...采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。而数据表是会持续更新的,索引统计信息也不会固定不变。...所以,当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。...索引选择异常和处理 采用 force index 强行选择一个索引。MySQL 会根据词法解析的结果分析出可能可以使用的索引作为候选项,然后在候选列表中依次判断每个索引需要扫描多少行。...如果 force index 指定的索引在候选索引列表中,就直接选择这个索引,不再评估其他索引的执行代价。 可以考虑修改语句,引导 MySQL 使用我们期望的索引。语义的逻辑是相同的。
mysql为什么选错索引? 在进行慢SQL分析的时候,有时候我们会发现explain的扫描行数和慢日志中的行数相差很大,那explain中的rows这个扫描行数是怎么判断的?...Mysql是通过采样统计的方法。为什么要采样统计呢?因为把整张表取出来一行行统计,虽然可以得到精确的结果,但是代价太高了,所以只能选择“采样统计”。...采样统计的时候,InnoDB默认会选择N个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。 而数据表是会持续更新的,索引统计信息也不会固定不变。...所以,当变更的数据行数超过1/M的时候,会自动触发重新做一次索引统计。...在MySQL中,有两种存储索引的方式,可以通过设置参数innodb_stats_persistent的值来选择: 当设置为on的时候,表示统计信息会持久化存储。这时,默认的N是20,M是10.
一个经典的MySQL索引问题 今天分享一个线上的经典MySQL索引问题。 01背景介绍 今天在线上运维过程中,遇到了一个MySQL的经典索引问题。...那么对于这两个SQL,MySQL会采用何种执行计划呢?...为什么第2个SQL的限制条件更多,但是却能用到索引,第一个SQL的限制条件更少,却用不到索引? 真实情况是什么样子的?...扫描行数100的,采用的方法1,先索引查询,再回表; 扫描行数19900的,采用的方法2,直接查聚集索引。 03 为什么会有这种差异呢? MySQL优化器的逻辑是关键。...MySQL中,决定一个查询究竟用哪个索引的过程,可以简单模拟成下面这样: 1、根据搜索条件,找到所有可能的索引,并逐一计算走每条索引的代价 2、计算全表扫描的代价 3、对比各种执行方案,选出成本最低的一个
(计算、函数、自动/手动类型转换) MYSQL索引类型 索引类型 1....普通索引 (index) 2. 唯一索引 (unique) 在普通索引的基础上,会进行排除重复值 3....主键索引 (primary key) 和唯一索引的区别在于一个表里只能有一个主键索引,但是唯一索引可以有多个。 4....全文索引 (fulltext) 普通索引/唯一索引/主键索引 哪个速度更快? 速度是一样的快,因为三者都是采用btree二叉树算法进行查找。...为什么不默认采用HASH索引呢? HASH只能用在=和上,所以功能受限,所以默认采用BTREE。
明明也是字符串,为什么字符串里含有emoji表情,插入就会报错呢? 我们从字符集编码这个话题开始聊起。...字符和字符集的关系 mysql的字符集 想看下mysql支持哪些字符集。...mysql建表时如果不知道该选什么字符集,无脑选utf8mb4就行了,你会感谢我的。...后来交接给了B同学,B同学在这基础上加过非常多的字段,离职前最后一个需求加的这个名称字段,所幸并没炸雷。最后到了我这里。 好一个击鼓传雷。 有点东西哦。 那么问题来了。...这样的一个事故,复盘会一开,会挂P几呢?
如何检查SQL语句是否用到索引? 使用“EXPLAIN sql语句”进行调试,查看possible_keys或key possible_keys:可能应用的索引 key:实际使用的索引 ?...不能在索引上做任何操作(计算、函数、自动/手动类型转换) MYSQL索引类型 索引类型 1. 普通索引 (index) 2....唯一索引 (unique) 在普通索引的基础上,会进行排除重复值 3. 主键索引 (primary key) 和唯一索引的区别在于一个表里只能有一个主键索引,但是唯一索引可以有多个。 4....全文索引 (fulltext) 普通索引/唯一索引/主键索引 哪个速度更快? 速度是一样的快,因为三者都是采用btree二叉树算法进行查找。...为什么不默认采用HASH索引呢? HASH只能用在=和上,所以功能受限,所以默认采用BTREE。
可能有小伙伴会问,如果建表的时候,没有指定主键呢? 如果在创建表时没有显示的定义主键,则InnoDB存储引擎会按如下方式选择或创建主键。 首先判断表中是否有非空的唯一索引,如果有,则该列即为主键。...图片来自《MySQL 是怎样运行的:从根儿上理解 MySQL》 这其实就是一颗B+树,也是一个聚集索引,即数据和索引在一块。...《MySQL实战45讲》 非聚集索引 ?...因为idx_name_age索引的叶子节点存的值为主键值,name值和age值,所以从idx_name_age索引上就能获取到所需要的列值,不需要回表,即索引覆盖 仔细看一下联合索引这个图,你就基本上能明白为什么不满足最左前缀原则的索引会失效...索引为什么会失效? 当别人问我索引在什么条件下会失效时,我能背出一大堆规则 不要在索引列上进行运算或使用函数 前导模糊查询不会使用索引,例如 like %李 负向条件索引不会使用索引,建议用in。
为什么不采用二叉树 假设此时用普通二叉树记录 id 索引列,我们在每插入一行记录的同时还要维护二叉树索引字段。...但 MySQL 的索引依然 不采用 能够精准定位的 Hash 表 。因为它 不适用 于 范围查询 。 3....为什么不采用红黑树 红黑树是一种特化的 AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡; 若一棵二叉查找树是红黑树,则它的任一子树必为红黑树。...但 MySQL 的索引依然 不采用 能够精确定位和范围查询都优秀的 红黑树 。...因为当 MySQL 数据量很大的时候,索引的体积也会很大,可能内存放不下,所以需要从磁盘上进行相关读写,如果树的层级太高,则读写磁盘的次数(I/O交互)就会越多,性能就会越差。 4.
为什么不采用二叉树 假设此时用普通二叉树记录 id 索引列,我们在每插入一行记录的同时还要维护二叉树索引字段。...[图片] 但 MySQL 的索引依然不采用能够精准定位的Hash 表。因为它不适用于范围查询。...[图片] 但 MySQL 的索引依然不采用能够精确定位和范围查询都优秀的红黑树。...因为当 MySQL 数据量很大的时候,索引的体积也会很大,可能内存放不下,所以需要从磁盘上进行相关读写,如果树的层级太高,则读写磁盘的次数(I/O交互)就会越多,性能就会越差。...这也就是为什么 MySQL 的表有上千万数据的情况下,查询效率依然快的原因。
其创作的《MySQL实战45讲》专栏受众已逾2万人。 你一定知道了,索引的作用是加快查询速度。...加索引的代价 在MySQL的老版本里,由于加索引和加字段是会锁表的,这个期间表上不能更新,因此不能直接在业务库上操作。...如果是用的MySQL5.6及之后的版本,并且操作的是小表,比如加索引的执行时间不超过5分钟,由于不会导致明显的延迟,是可以直接在线执行的。当然我还是会建议你在低峰期执行这个操作。...pt-ost加索引 那你会问了,如果是大表加索引,怎么解决这个延迟的问题呢?...看这个参数名的字面意思,好像是在加唯一索引之前会判断一下这个操作是否会丢数据。 实际上是不是这样呢?我们来看一个例子。假设我现在在一个空表上用pt-ost工具加一个唯一索引,执行的命令如下: .
领取专属 10元无门槛券
手把手带您无忧上云