前言 前几天,有位童鞋咨询我一个问题,如果表新增一个not null字段、不指定default,那么这个操作能成功吗?当时我不假思索地回答会直接报错,结果当然就是被啪啪打脸。...后续回顾这个问题,做出此错误回答的原因有那么几个:一是not null和不指定default两者本身是冲突的;二是Oracle相关经验告诉我会报错;三是MySQL开发规范一般要求指定default;接下来我们详细记录一下这个案例...MySQL是如何处理的? 看完了Oracle,我们再来看一下MySQL是如何处理的。...对于新增not null字段、不指定default的处理方式,是不够严谨的;数据库自己指定一个default,是有可能会造成一些脏数据的,毕竟类似0、当前时间这些数值,本身可能是具有业务意义的;因此,这也是为什么...MySQL开发规范一般要求指定default 总结 对于表新增not null字段、不指定default的处理方式,Oracle和MySQL是不一样的,具体总体如下: (1)对于Oracle而言,如果表为空
01、MySQL中null值的一个小坑 今天在测试null值的时候,发现了一个小问题,记录在这里,不知道大家以前遇到过没。...事情发展是这样的,在过滤一个表中的数值的时候,需要把age=2的列给剔除掉,然后查看剩余的列信息,这个操作看起来比较简单,我用一个表模拟一下过程: CREATE TABLE `test` ( `id...=2是无法得到全量的查询结果的,这明显不符合我们的预期。...其实这个问题,在之前的4月29号的文章中有说到过,就是在一条数据记录里面,null值字段和一般的字段是不在一起存储的,null值字段是存储在null值列表里面的。...所以造成了检索时候不匹配的现象,这个还是比较重要的一个点,希望对大家有用。 声明一下,测试环境是5.7.16版本的MySQL。
为什么Mysql 数据库尽量避免NULL? (1)如果查询中包含可为NULL的列,对Mysql来说更难优化,因为可为NULL的列使得索引,索引统计和值比较都更复杂。 (2)含NULL复合索引无效....(3)可为NULL的列会使用更多的存储空间,在Mysql中也需要特殊处理。...(4)当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。...MySQL索引失效的几种清空 1.索引不存储null值 更准确的说,单列索引不存储null值,复合索引不存储全为null的值。...'条件,由于前面是 模糊的,所以不能利用索引的顺序,必须一个个去找,看是否满足条件。
前几天分析了一个死锁的问题,有一个网友看了以后,就发了邮件给我问一个问题。一般来说,能够发送邮件提出问题的同学,都是很认真的,因为他要准备好日志,准备好操作过程,准备好他已经在做的事情。...这位网友提的一个问题,我看了以后感觉很是奇怪,因为有些颠覆我对MySQL锁的一些认识。这该如何是好。 这个环境的事务隔离级别是RR,存在主键,存在范围查询。...但是MySQL 5.7中出现这个问题,自己还是带着一丝的侥幸心理,在MGR上测试了一把,能够复现,结果今天继续耐着性子看了下这个问题,在5.6上模拟了一下,5.6全然没有这个问题,问题到了这里,就有了柳暗花明的一面...,能够肯定的是这个问题在MySQL 5.7中可以复现,在MySQL 5.6中是正常的。...而有看点的是问题的提出者定位到了相关的代码,还是希望文档的部分能够把间隙锁的部分补充一下。
引入问题 这个问题来源于一个网络课程的课后思考题,题目是这样的: 我用下面的表结构和初始化语句作为试验环境,事务隔离级别是可重复读。...mysql> CREATE TABLE `test2` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id...补充解释下这个问题,mysql环境,innodb引擎,事务的隔离级别是可重复读,一个表只有两个字段,然后插入4条数据,希望你构造上图中的一种情况,就是明明update了,但是结果没有更新,select也好像没有生效...给出问题的答案 先直接给出答案吧, 开启两个mysql的交互窗口,模拟两个事物的操作,比如一个事物叫A,一个事物叫B。...一致性读是读取在某个时间点已经提交了的数据, 在本示例中,这个时间点就是 start transaction with consistent snapshot执行的时间点。
经常会看到这样的例子: 当你需要统计表中有多少数据的时候,会经常使用如下语句 SELECT COUNT(*) FROM demo_info; 由于聚集索引和非聚集索引中的记录是一一对应的,而非聚集索引记录中包含的列...如果我们使用非聚集索引执行上述查询,即统计一下非聚集索引uk_key2中共有多少条记录,是比直接统计聚集索引中的记录数节省很多I/O成本。所以优化器会决定使用非聚集索引uk_key2执行上述查询。...——基于MySQL 8.0.22索引成本计算 分析一下执行计划 在执行上述查询时,server层会维护一个名叫count的变量,然后: server层向InnoDB要第一条记录。...InnoDB找到uk_key2的第一条二级索引记录,并返回给server层(注意:由于此时只是统计记录数量,所以并不需要回表)。 由于count函数的参数是*,MySQL会将*当作常数0处理。...,所以其实读取任意一个索引中的记录都可以获取到id字段,此时优化器也会选择占用存储空间最小的那个索引来执行查询。
1、两个同样结构的语句一个没有用到索引的问题: 查1到20号的就不用索引,查1到5号的就用索引,为什么呢?不稳定?...2、再看个例子: 今天遇到一个奇怪的问题,明明已经建立了索引,select语句的explain也表明会利用这个索引,可是结果偏偏没有用索引,最后扫描了全表。 ...可能是主键索引会比普通index更快,所以mysql最后选择了数据量跟大的id索引。 那么,如何解决这个问题呢? ...f=wb 3、本质原因:Cardinality(索引基数) 很关键的一个参数,平均数值组=索引基数/表总数据行,平均数值组越接近1就越有可能利用索引。...索引选择性是不重复的索引值也叫基数(cardinality)表中数据行数的比值,索引选择性=基数/数据行,基数可以通过“show index from 表名”查看。
---- 在满足语句需求的情况下,尽量少的访问资源是数据库设计的重要原则,这和执行的 SQL 有直接的关系,索引问题又是 SQL 问题中出现频率最高的,常见的索引问题包括:无索引(失效)、隐式转换。...2.3 索引下推 以人员表的联合索引(name, age)为例。如果现在有一个需求:检索出表中“名字第一个字是张,而且年龄是26岁的所有男性”。...修改应用,将应用中传入的字符类型改为与表结构相同类型。 3. 为什么会选错索引 3.1 优化器 选择索引是优化器的工作,其目的是找到一个最优的执行方案,用最小的代价去执行语句。...显然,一个索引上不同的值越多,索引的区分度就越好,而一个索引上不同值的个数我们称为“基数”,也就是说,这个基数越大,索引的区分度越好。...使用采样统计方法来估算基数: 采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。
一、伏笔篇(1)优化器索引选择影响因素?选择索引是优化器的工作,而优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。...而一个索引上不同的值的个数,我们称之为“基数”(cardinality)。也就是说,这个基数越大,索引的区分度越好。(3)MySQL索引基数计算方法?为什么要采样统计呢?...采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。而数据表是会持续更新的,索引统计信息也不会固定不变。... # 索引中的列序号column_name # 列名称collation # 列以什么方式存储在索引中,在mysql中,有值'A'(升序)或者NULL(无分类)cardinality...另外官网也对Cardinality(基数)值做了详细说明,其大小并不是一个准确值,而是一个采样预估值,通过analyze table操作可以更新Cardinality(基数)预估值的大小,从而影响优化器对索引的选择
上篇文章介绍了用索引列分组也可以提高效率,及其回表的代价,回表是二级索引+回表查询,如果回表数据量太庞大,mysql优化器就会采用全表扫描查询,而覆盖索引不会回表。...考虑列的基数 列的基数是指某一列中不重复的数据,比如name列有3,2,3,5,5,3,2,3,3,虽然数据有不少,但是他的不同数据只有三,所以基数是3。...在数据记录中,列的基数越大,说明数据越分散,列的基数越小,说明数据越集中。...假设列的基数是1,那当前列所有数据都一样,就无法排序,建立索引是没有意义的,如果建立二级索引,还会因为大量数据的回表操作而损耗性能,所以只有列基数越大的时候,才适合建立索引。...我们之前说过,对于字符串的列,是一个字符一个字符比较排序的,所以索引设计者,考虑到空间和时间,只对字符串前几个指定字符进行存储和排序,这样也能相对定位到所在的位子,在用对应的主键id去聚簇索引的b+树查询所有值
一个索引上不同的值越多,区分度越高。一个索引上的不同值的个数称之为基数。 -- 查看表t上的索引基数 show index from t; 该索引基数不是准确的,是采样获得。 索引基数如何获取?...采样统计时,InnoDB会默认选择N个数据页,统计这样写页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,结果即索引的基数。...MySQL中有两种存储索引统计的方式,可以通过设置参数innodb_stats_persistent 的值来选择: 设置为on,表示统计信息会持久化存储,N为20,M为10 设置为off,表示统计信息只存储在内存中...原因是全表扫描是在主键索引上扫描,没有回表操作的额外代价,优化器会自己估算全表扫描和索引a的代价,从上述结果来看,优化器认为全表扫描更加快捷,但是我们通过慢日志可以看出优化器的这个选择并不是最优解。...可以使用force index强制走某个索引,但该方法弊端过于明显,索引名称变更受影响,如果迁移到别的数据库语法不兼容 修改SQL语句,引导MySQL优化器选择正确的索引 新建一个更合适的索引,删除误用的索引
ANALYZE 在MySQL里提交一条查询SQL语句时,优化器会选在一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。...扫描的行数越少,意味着资源资源越少,扫描行数是怎么判断,是通过索引的基数来得到值和row。 mysql>SHOW INDEX FROM table_name ?...采样统计的时候InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。而数据表是会持续更新的,索引统计信息也不会固定不变。...上面是2次,ANALYZE TABLE命令进行修复索引。在不停的浮动。 分析表通过对每个索引树执行随机潜水并相应地更新索引基数估计值来确定索引基数,所以这个值也不是100%准确。...3)选择直方图判断逻辑是:如果指定的桶数大于或等于桶数 对于不同的值,创建一个单例直方图。否则创建一个等高直方图。 ?
分支索引页中存放分段stu_id的起始值,以及值所对应的叶子索引页号 叶子索引页中存放排序后的stu_id值,该值所对应的表页号, 下一个叶子索引页的页号 ?...系统是通过索引的区分度来判断的,一个索引上不同的值越多,意味着出现相同数值的索引越少,意味着索引的区分度越高。我们也把区分度称之为基数,即区分度越高,基数越大。...所以呢,基数越大,意味着符合 100 的行数越少。 所以呢,一个索引的基数越大,意味着走索引查询越有优势。 那么问题来了,怎么知道这个索引的基数呢?...系统当然是不会遍历全部来获得一个索引的基数的,代价太大了,索引系统是通过遍历部分数据,也就是通过采样的方式,来预测索引的基数的。...既然会预测错索引的基数,这也意味着,当我们的查询语句有多个索引的时候,系统有可能也会选错索引,这也可能是 SQL 执行的很慢的一个原因。 下面做一个总结。
mysql> CREATE TABLE `t` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT...系统是通过索引的区分度来判断的,一个索引上不同的值越多,意味着出现相同数值的索引越少,意味着索引的区分度越高。我们也把区分度称之为基数,即区分度越高,基数越大。...所以呢,基数越大,意味着符合 100 的行数越少。 所以呢,一个索引的基数越大,意味着走索引查询越有优势。 那么问题来了,怎么知道这个索引的基数呢?...系统当然是不会遍历全部来获得一个索引的基数的,代价太大了,索引系统是通过遍历部分数据,也就是通过采样的方式,来预测索引的基数的。...既然会预测错索引的基数,这也意味着,当我们的查询语句有多个索引的时候,系统有可能也会选错索引哦,这也可能是 SQL 执行的很慢的一个原因。
,我解决这个问题的方法如下: 1、先查看了一下慢日志中的内容,发现慢日志中没有具体的记录。...,一个普通索引,这个普通索引包含appid、accountid、accounttype以及uid这4个字段,是联合索引,查看了一眼表中的数据量,大概有5w多条,并不算很多。...这个时候,我已经开始怀疑这个表的索引创建的是否有问题了,于是首先查看了一眼表中的数据,看看appid的值都包含哪些吧。...6、修改索引字段 我们再来看这个联合索引: key appid(appid,accountid,accounttype,uid) 这样明显是不合理的,因为appid和accounttype的值基数太小...,只有1,索引这个索引应该修改,具体的改法有很多,我是通过修改联合索引的先后顺序,将基数大的字段放在前面,这样扫描的时候能够过滤的更加准确一些。
这篇主要介绍 MySQL 索引的 Cardinality 值(基数)以及索引的可选择性。 索引基数值 索引基数的含义: 由索引中唯一值计算的一个预估值。...索引基数值的准确程度直接影响到 MySQL 优化器基于此索引的查询计划是否准确高效。...影响索引基数值的相关指标: 表的 sample page 个数, 也就是表样例数据页的个数,这个在之前表样例数据计算中详细讲过。...不同的是 SQL 2 打印符合过滤条件的记录,而 SQL 3 是打印符号过滤条件的记录条数。...索引 idx_r6 的基数其实很高了,但是由于最终返回的记录数太多,MySQL 只能放弃走索引;而 SQL 3 由于只求符合过滤条件的记录数,直接从索引入口就可以计算出来结果。
· Non_unique 如果索引不能包括重复词,则为0。如果可以,则为1。 · Key_name 索引的名称。 · Seq_in_index 索引中的列序列号,从1开始。...· Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。 · Cardinality 索引中唯一值的数目的估计值。...基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。...· Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。 · Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。...· Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。 · Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
查看索引 mysql> show index from tblname; mysql> show keys from tblname; · Table 表的名称。...· Non_unique 如果索引不能包括重复词,则为0。如果可以,则为1。 · Key_name 索引的名称。 · Seq_in_index 索引中的列序列号,从1开始。...· Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。 · Cardinality 索引中唯一值的数目的估计值。...基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。...· Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。 · Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。
mysql> CREATE TABLE `t` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL...系统是通过索引的区分度来判断的,一个索引上不同的值越多,意味着出现相同数值的索引越少,意味着索引的区分度越高。我们也把区分度称之为基数,即区分度越高,基数越大。...所以呢,基数越大,意味着符合 100 的行数越少。 所以呢,一个索引的基数越大,意味着走索引查询越有优势。 那么问题来了,怎么知道这个索引的基数呢?...系统当然是不会遍历全部来获得一个索引的基数的,代价太大了,索引系统是通过遍历部分数据,也就是通过采样的方式,来预测索引的基数的。...既然会预测错索引的基数,这也意味着,当我们的查询语句有多个索引的时候,系统有可能也会选错索引哦,这也可能是 SQL 执行的很慢的一个原因。
什么是索引? “索引(在MySQL中也叫“键key”)是存储引擎快速找到记录的一种数据结构。”...注意:一个表只能有一个主键。 唯一索引 UNIQUE:唯一索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。...3、索引设计的原则 1)适合索引的列是出现在where子句中的列,或者连接子句中指定的列; 2)基数较小的类,索引效果较差,没有必要在此列建立索引; 3)使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度...回表:当对一个列创建索引之后,索引会包含该列的键值及键值对应行所在的rowid。通过索引中记录的rowid访问表中的数据就叫回表。...索引优化规则: 1)如果MySQL估计使用索引比全表扫描还慢,则不会使用索引。 返回数据的比例是重要的指标,比例越低越容易命中索引。
领取专属 10元无门槛券
手把手带您无忧上云