(python画派大星)(python派大星的颜色)

(python画派大星)(python派大星的颜色)
(python画派大星)(python派大星的颜色)

(python画派大星)(python派大星的颜色)

MySql 中使用 or 条件会走索引吗?

(python画派大星)(python派大星的颜色)

MySql 版本5.6

1、 a 是索引,b 不是

(python画派大星)(python派大星的颜色)

● 在 InnoDB 中,MySql 全表扫描,不走索引

我们思考下,如果 MySql 走索引 a,由于b不是索引,需要全表扫描,最后还需要merge求并集。结果就是:索引扫描 + 全表扫描 + merge 处理。如果是你,你愿意全表扫描还是走索引?

2、 a 和 b 都是索引

● 在 InnoDB 中,MySql 走索引

(python画派大星)(python派大星的颜色)

我们可以看到,当 a,b 都是索引时,使用了索引 idx_a 和 idx_b,

type的信息:index_merge

extra中的信息:

Using union(idx_a,idx_b);Using where

3、index merge

注意:MySQL5.0之前,一个表一次只能使用一个索引,无法同时使用多个索引分别进行条件扫描。但是从5.1开始,引入了 index merge 优化技术,对同一个表可以使用多个索引分别进行条件扫描。

同一个表的多个索引的范围扫描可以对结果进行合并,合并方式分为三种:union, intersection, 以及它们的组合(先内部intersect然后在外面union)

对于 or 条件,,index uion merge 就是多个索引条件扫描,对得到的结果进行并集运算。

MySql 中的 varchar 字段是如何建立索引的?

依据《阿里巴巴》开发手册 -- MySql索引规约

●【强制】业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引

说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。

●【强制】在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可

说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分 度会高达 90%以上,可以使用 count(distinct left(列名, 索引长度))/count(*)的区分度 来确定。

(python画派大星)(python派大星的颜色)

如果在 email 字段上建立索引:

(python画派大星)(python派大星的颜色)

这两种不同的定义在数据结构和存储上有什么区别呢?

(python画派大星)(python派大星的颜色)

index1

(python画派大星)(python派大星的颜色)

index2

举个栗子:

(python画派大星)(python派大星的颜色)

● 对于索引 index1

① 从 index1 索引树找到满足索引值是"zhangssxyz@xxx.com"的这条记录,取得 ID2 的值;

② 到主键上查到主键值是 ID2 的行,判断 email 的值是正确的,将这行记录加入结果集;

③ 取 index1 索引树上刚刚查到的位置的下一条记录,发现已经不满足email="zhangssxyz@xxx.com"的条件了,循环结束。

(python画派大星)(python派大星的颜色)

● 对于索引 index2

① 从 index2 索引树找到满足索引值是’zhangs’的记录,找到的第一个是 ID1;

② 到主键上查到主键值是 ID1 的行,判断出 email 的值不是’zhangssxyz@xxx.com’,这行记录丢弃;

③ 取 index2 上刚刚查到的位置的下一条记录,发现仍然是’zhangs’,取出 ID2,再到 ID 索引上取整行然后判断,这次值对了,将这行记录加入结果集;

④ 重复上一步,直到在 idxe2 上取到的值不是’zhangs’时,循环结束。

使用前缀索引后,可能会导致查询语句读数据的次数变多。如果我们定义的 index2 不是 email (6) 而是 email (7),也就是说取 email 字段的前 7 个字节来构建索引的话,即满足前缀’zhangss’的记录只有一个,也能够直接查到 ID2,只扫描一行就结束了。

如何确定字符串索引的长度?

可以使用 count(distinct left(列名, 索引长度))/count(*) 来确定,找出不小于90%的值

(python画派大星)(python派大星的颜色)

● 前缀索引对覆盖索引的影响

(python画派大星)(python派大星的颜色)

这个语句只要求返回 id 和 email 字段。

所以,如果使用 index1的话,可以利用覆盖索引,从 index1 查到结果后直接就返回了,不需要回到 ID 索引再去查一次。

而如果使用 index2(即 email (6) 索引结构)的话,就不得不回到 ID 索引再去判断 email 字段的值。

● 前缀索引区分度差

比如说身份证号,一共 18 位,其中前 6 位是地址码,所以同一个县的人的身份证号前 6 位一般会是相同的。

按照我们前面说的方法,可能你需要创建长度为 12 以上的前缀索引,才能够满足区分度要求。

但是,索引选取的越长,占用的磁盘空间就越大,相同的数据页能放下的索引值就越少,搜索的效率也就会越低。

其他解决方案:

① 倒序存储

由于身份证号的最后 6 位没有地址码这样的重复逻辑,所以最后这 6 位很可能就提供了足够的区分度。

(python画派大星)(python派大星的颜色)

使用 hash 字段。

你可以在表上再创建一个整数字段,来保存身份证的校验码,同时在这个字段上创建索引,索引的长度变成了 4 个字节,比原来小了很多。

(python画派大星)(python派大星的颜色)
(python画派大星)(python派大星的颜色)

注意:以上两种方案都有一个共同的缺点,不支持范围查找。我们需要具体情况具体分析。

MySql分页limit速度太慢优化方法

● 常用的 limit 用法

offset 是偏移量,默认是 0,rows 指预期检索的行数

(python画派大星)(python派大星的颜色)
(python画派大星)(python派大星的颜色)

如果 offset = 1000000 ,rows = 10 时,意味着扫描符合条件的 1000010 行,只要最后 10 行记录。

《阿里巴巴手册》中对 MySql 分页做了如下说明:

●【推荐】利用延迟关联或者子查询优化超多分页场景

说明:

MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回 N 行,那当 offset 特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特定阈值的页数进行 SQL 改写。

正例:

(python字典怎么合并)(python向字典合并)

先快速定位需要获取的 id 段,然后再关联:

SELECT a.* FROM 表 1 a, (select id from 表 1 where 条件 LIMIT 100000,20) b where a.id=b.id

● 解决 limit 分页常用方案

如果之前有关注 Python大星的老铁们,应该看过一篇文章

(python求个数的函数)(python的求值函数)

,我们从头条文章分页接口可“管中窥豹”。

每次取出最大时间 max_behot_time

(python画派大星)(python派大星的颜色)

max_behot_time 加上索引

如果能使用覆盖索引,可以建立联合索引,避免回表查询

(python画派大星)(python派大星的颜色)

Python大星 曾去京东面试

(python画派大星)(python派大星的颜色)

有一道 MySql 的面试题留下深刻的印象

题意大致如下:

假设有一个软件,每次用户开机会提示“你打败了全国电脑 **% 的电脑”,如果是你,你会怎么设计MySql 数据库(考虑大数据量的情况)

欢迎各位老铁踊跃发言

没错,说的就是你!!!

(python画派大星)(python派大星的颜色)

>>>

声明:我要去上班所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,版权归原作者所有,原文出处。若您的权利被侵害,请联系删除。

本文标题:(python画派大星)(python派大星的颜色)
本文链接:https://www.51qsb.cn/article/4094.html

(0)
打赏微信扫一扫微信扫一扫QQ扫一扫QQ扫一扫
上一篇2022-09-09
下一篇2022-09-11

你可能还想知道

发表回复

登录后才能评论