MySQL原理(四)索引(3)索引失效与索引区分度

一、索引失效:

首先未使用索引列作为查询条件索引是肯定会生效的,还有其他的情况,索引列做为了查询条件也失效了:

 ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos(NAME, age, pos);

1、select 语句、order by语句:和索引无关;

2、where语句索引失效:

(1)组合索引失效:如果索引了多列,要遵守最左前缀法则,Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但必须包含最左侧的一个。例如索引是index (a,b,c),可以支持a | a,b| a,b,c |a,c这几种组合进行查找,但不支持 b|b,c|c进行查找 。如

注:

组合索引最好全值匹配(查询条件的顺序和索引的顺序一致,这种方式最好,能够充分发挥索引的作用,当然使用and连接的查询提交也可以不与索引的顺序一致,mysql会自动优化,如index(a,b,c),where a= and b= and c= 与where b= and c= and a=,...效果是一样的 

(2)列类型是字符串,查询条件未加引号;

(3)使用like时通配符在前会导致索引失效,通配符在后面时效率不受影响,所以一般使用右模糊:

(4)查询条件中使用or会使索引失效,要想是索引生效,需要将or中的每个列都加上索引;

(5)对索引列进行计算、函数、(自动or手动)类型转换会导致索引失效,如where substr(a, 1, 3) = ‘hhh’、where a = a+1、DATE_FORMAT函数等;

注意:索引失效指的是where条件不当引起的失效,如这里计算放在select后面是不会引起索引失效的。

(6)mysql 在使用不等于(!= )的时候无法使用索引,会导致全表扫描;

(7)使用in查询,当in()括号里面只有一个时,索引有效;否则无效。如表zt_test现有数据和索引如下:

 现在查询:

当in的条件多于1个时,

小结:假设index(a,b,c):

sql有没有用到索引,有的话用到了哪些
where c=1 and b=1 and a='aaa'  用到了a,b,c
where a = 'aaa'  and c=1 用到了a,没有用到c
where a like '%aaa%' and b=1 and c=1  没有用到
where a like 'aaa%' and b=1 and c=1 用到
where a ='aaa' and b like '1%' and c=1用到了a和b, c在模糊查询的通配符之后,断了
where a = 111 and b =1 and c=1 没有用到
where a = 'aaa' or b =1 or c=1   没有用到
where a!='aaa' and b =1 and c=1 没有用到
where (a+'aa')!='aaa'  没有用到
ORDER BY a  没有用到
GROUP  BY a 用到

二、索引长度与索引区分度

在SQL执行计划中,key_len 表示索引长度,经常用于判断复合索引是否被完全使用。

注:在utf8编码方式下,一个字符占3个字节;utf8mb4一个字符占4个字节;gbk中一个字符占2个字节;latin中一个字符占1个字节。索引长度可以指定,不指定的情况下会按照规则使用默认的长度。

1、默认索引长度定义:

在没有指定索引长度的情况下,如果索引字段不为空且长度不可变,索引长度等于该字段的长度;可以为null,mysql会用1个字节标识;长度可变,MySQL会使用2个字节标识。以utf8编码为例

(1)如果索引字段不为空且长度不可变,索引长度等于该字段的长度;

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

随便插入几条数据:

    

 索引查询: key_len = 60,索引段name的长度是20个字符,key_len = 20*3 = 60。

   

(2)如果索引字段不为空,长度可变:改成varchar:

   

查询:key_len = 20*3 +2= 62

(3)如果索引字段可以为空,长度不可变:

    

  查询:key_len = 20*3 +1= 61

  

(4)以此类推,字段既可以为空长度也可变,索引长度+2+1:

   

查询:

  

(5)复合索引:索引列长度之和

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `address` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_name_address` (`name`,`address`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

   

 key_len长度为63,说明只用到了复合索引的前半部分;

 key_len长度为126,说明该SQL查询语句用了整个复合索引。

 综上,key_len 表示索引长度,经常用于判断复合索引是否被完全使用。

2、指定索引长度:
CREATE INDEX index_name ON table_name column_name(length);

 如对于表

 设置索引长度:

ALTER TABLE test ADD INDEX index_name_address (`name`(10),`address`(10));

 

 key_len = 10*3+2+1+10*3+2+1=66。

3、索引区分度:

区分度百分比 = select count(distinct left(索引字段,索引长度))/count(1) from table。区分度越高,查询越快,如主键索引,主键是唯一的,主键索引的区分度就是1。区分度低的索引原则上已失去意义,没有明显的查询效率,而且添加了索引每次查询会先走索引树,再回表查询,增加了额外的io消耗,就不如直接查询原表来的效率高

4、总结:

索引长度和区分度是相互矛盾的,索引长度太短,那么区分度就很低,把索引长度加长,区分度就高,但是索引也是要占内存的,所以我们需要找到一个平衡点。

举个例子:(张,张三,张三哥),如果索引长度取1的话,那么每一行的索引都是 张 这个字,完全没有区分度,无法排序,结果这样三行完全是随机排的,因为索引都一样;如果长度取2,那么排序的时候至少前两个是排对了的,如果取3,区分度达到100%,排序完全正确;但是并不是索引越长越好,比如 (张,李,王) 和 (张三啦啦啦,张三呵呵呵,张三呼呼呼);前者在内存中排序占得空间少,排序也快,后者明显更慢更占内存,在大数据应用中这一点点影响都是很大的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/363873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

x2openEuler 升级实操(centos7.8 to openEuler 20.03)

通过 x2openEuler 工具,将 centos 7.8 迁移至 OpenEuler 上,实际感受迁移过程。x2openEuler https://docs.openeuler.org/zh/docs/20.03_LTS_SP1/docs/x2openEuler/x2openEuler.html 环境准备 下载 x2openEuler 安装包 wget https://repo.oepkgs.net/o…

Nicn的刷题日常之带空格直角三角形图案

1.题目描述 描述 KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的带空格直角三角形图案。 输入描述: 多组输入,一个整数(2~20),表示直角三角形直角边的长度&am…

Linux 指令

Linux 指令 1 登入/登出1.1 关机1.2 重启1.3 切用户 2 文件和目录管理2.1 目录操作2.2 文件操作2.3 文件内容操作2.4 归档及压缩 3 文本编辑器 vim3.1 命令模式3.2 输入模式3.3 末行模式 4 用户和组管理4.1 用户和组帐号概述4.1.1 用户帐号4.1.2 UID和GID 4.2 用户管理 5 组管理…

算法:箱子之形摆放

一、算法描述及解析 要求将一批箱子按从上到下以‘之’字形的顺序摆放在宽度为 n 的空地上,输出箱子的摆放位置, 例如:箱子ABCDEFG,空地宽为3。 如输入: ABCDEFG 3 输出: AFG BE CD 注:最后一行…

leetcode 28.找出字符串中第一个匹配项的下标(python版)

需求 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。 如果 needle 不是 haystack 的一部分,则返回 -1 。 示例 1: 输入:haystack…

2023年OceanBase开发者大会:核心内容与学习收获(附大会核心PPT下载)

本次大会邀请了众多业界领袖、技术大咖和开发者,共同探讨数据库领域的技术发展趋势和未来机会,与开发者共同探讨单机分布式、云原生、HTAP 等数据库前沿趋势,分享全新的产品 roadmap,交流场景探索和最佳实践。 一、大会核心内容 …

v-if及v-for、computed计算属性的使用

v-if 概念及使用 v-if是Vue.js中的一个指令&#xff0c;用于根据表达式的真假值条件性地渲染一块内容。如果表达式的值返回真&#xff0c;则Vue会渲染这块内容&#xff1b;如果返回假&#xff0c;则不渲染。 基本用法: <p v-if"isVisible">看到我了吗&#…

【vim 学习系列文章 3.2 -- vim 删除 空格】

文章目录 vim 删除行尾空格 vim 删除行尾空格 在代码开发的过程中&#xff0c;经常会遇到行尾有空格的现象&#xff0c;如下&#xff1a; 我们可以在 .vimrc 中通过map 命令来映射删除行尾空格的快捷键&#xff0c;如下&#xff1a; map d<space> :%s/\s*$//g <cr…

3分钟彻底搞懂Web UI自动化测试之【POM设计模式】

为什么要用POM设计模式 前期&#xff0c;我们学会了使用PythonSelenium编写Web UI自动化测试线性脚本 线性脚本&#xff08;以快递100网站登录举例&#xff09;&#xff1a; import timefrom selenium import webdriver from selenium.webdriver.common.by import Bydriver …

尚硅谷Ajax笔记

一天拿下 介绍二级目录三级目录 b站链接 介绍 ajax优缺点 http node.js下载配置好环境 express框架 切换到项目文件夹&#xff0c;执行下面两条命令 有报错,退出用管理员身份打开 或者再命令提示符用管理员身份打开 npm init --yes npm i express请求 <script>//引…

【Docker】使用VS创建、运行、打包、部署.net core 6.0 webapi

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

《Pandas 简易速速上手小册》第6章:Pandas 时间序列分析(2024 最新版)

文章目录 6.1 时间序列数据基础6.1.1 基础知识6.1.2 重点案例&#xff1a;股票市场分析6.1.3 拓展案例一&#xff1a;温度变化分析6.1.4 拓展案例二&#xff1a;电商平台日销售额分析 6.2 日期与时间功能6.2.1 基础知识6.2.2 重点案例&#xff1a;活动日志分析6.2.3 拓展案例一…

022 do while循环

什么是do while循环 int i 0; do {System.out.println(i);i; } while (i < 100); 具体使用场景 int i; Scanner scanner new Scanner(System.in); do {System.out.print("请输入一个整数&#xff0c;如果为负数则结束循环&#xff1a;");i scanner.nextInt(…

基于极大似然法和最小二乘法系统参数辨识matlab仿真,包含GUI界面

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 1.极大似然法系统参数辨识 2. 最小二乘法系统参数辨识 5.完整程序 1.程序功能描述 分别对比基于极大似然法的系统参数辨识以及基于最小二乘法的系统参数辨识&#xff0c;输出起参数辨识收敛…

Scrum敏捷研发管理全流程/scrum管理工具

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 Leangoo领歌上手快、实施成本低&#xff0c;可帮助企业快速落地敏捷&#xff0c;提质增效、缩短周期、加速创新…

二进制、原码、反码、补码

一、 二进制在运算中的说明 二、原码、反码、补码 1、二进制的最高位是符号位&#xff1a;0表示正数&#xff0c;1表示负数 2、正数的原码、反码、补码相同&#xff08;三码合一&#xff09; 3、负数的反码它的原码符号位不变&#xff0c;其它位取反&#xff08;0变1,1变0&…

【leetcode】20. 有效的括号

有效的括号 题目链接 // 栈结构 typedef char valuetype; typedef struct {valuetype* arr;int top;int capacity; } Stack;void Init(Stack* stack);void Push(Stack* stack, valuetype value); void Pop(Stack* stack);valuetype Top(Stack* stack); int Size(Stack* stack…

数据结构+算法(第06篇):再不会“降维打击”你就Out了!

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

各类型判空操作

开发中经常遇到需要判空的地方&#xff0c;比如对字符串进行判空操作。 而有时候工具包太多不知道用哪个。 就像下图&#xff0c;光一个 StringUtils 就有十几个包弹出来。 怎么选&#xff1f; 其实用哪个都行。 最重要的是&#xff1a; 有一套自己用的顺手的工具。 或者…

Java基础数据结构之ArrayList源码分析

一.几个常量 这是默认容量 这两个是共享的空对象 这是真正存储元素的地方&#xff0c;现在还没有分配内存 二.构造方法 这是一个无参构造方法&#xff0c;此时让存储元素的数组指向了那个默认容量数组&#xff0c;此时该数组是一个空数组&#xff0c;长度为0. 这是给定初始容量…