MySQL 重复索引探讨(持续更新中...)

资料参考:http://xiezhenye.com/2015/01/%E6%89%BE%E5%88%B0-mysql-%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%AD%E7%9A%84%E4%B8%8D%E8%89%AF%E7%B4%A2%E5%BC%95.html

<一> 创建‘有问题的‘表

1.创建表test1

CREATE TABLE test1 (
  id int(11) NOT NULL,
  f1 int(11) DEFAULT NULL,
  f2 int(11) DEFAULT NULL,
  f3 int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY k1 (f1,id),
  KEY k2 (id,f1),
  KEY k3 (f1),
  KEY k4 (f1,f3),
  KEY k5 (f1,f3,f2)
)

2.创建表 test2

CREATE TABLE test2 (
  id1 int(11) NOT NULL DEFAULT 0,
  id2 int(11) NOT NULL DEFAULT 0,
  b int(11) DEFAULT NULL,
  PRIMARY KEY (id1,id2),
  KEY k1 (b)
)

<二> 存在问题的索引

1. 包含主键的索引

innodb 本身是聚簇表,每个二级索引本身就包含主键,类似f1,id 的索引,虽然实际没什么害处,但反映使用者对mysql 索引的不了解。而 id,f1 这种多余索引,会浪费存储空间,并影响数据更新性能。包含主键的索引用这样一句sql 就能全部找出来:

select c.*, pk from 
       (select table_schema, table_name, index_name, concat(‘|‘, group_concat(column_name order by seq_in_index separator ‘|‘), ‘|‘) cols 
         from INFORMATION_SCHEMA.STATISTICS 
         where index_name != ‘PRIMARY‘ and table_schema != ‘mysql‘
     group by table_schema, table_name, index_name) c,
       (select table_schema, table_name, concat(‘|‘, group_concat(column_name order by seq_in_index separator ‘|‘), ‘|‘) pk 
         from INFORMATION_SCHEMA.STATISTICS 
         where index_name = ‘PRIMARY‘ and table_schema != ‘mysql‘
     group by table_schema, table_name) p  
     where c.table_name = p.table_name and c.table_schema = p.table_schema and c.cols like concat(‘%‘, pk, ‘%‘);

结果:

2.重复的索引

包含重复前缀的索引,索引能由另一个包含该前缀的索引完全代替,是多余索引。多余的索引会浪费存储空间,并影响数据更新性能。这样的索引同样用一句 sql 可以找出来。

select c1.table_schema, c1.table_name, c1.index_name,c1.cols,c2.index_name, c2.cols from
       (select table_schema, table_name, index_name, concat(‘|‘, group_concat(column_name order by seq_in_index separator ‘|‘), ‘|‘) cols 
         from INFORMATION_SCHEMA.STATISTICS 
         where table_schema != ‘mysql‘ and index_name!=‘PRIMARY‘
     group by table_schema,table_name,index_name) c1,   
       (select table_schema, table_name,index_name, concat(‘|‘, group_concat(column_name order by seq_in_index separator ‘|‘), ‘|‘) cols 
         from INFORMATION_SCHEMA.STATISTICS 
         where table_schema != ‘mysql‘ and index_name != ‘PRIMARY‘
     group by table_schema, table_name, index_name) c2 
     where c1.table_name = c2.table_name and c1.table_schema = c2.table_schema and c1.cols like concat(c2.cols, ‘%‘) and c1.index_name != c2.index_name;

结果:

3. 低区分度索引

这样的索引由于仍然会扫描大量记录,在实际查询时通常会被忽略。但是在某些情况下仍然是有用的。因此需要根据实际情况进一步分析。这里是区分度小于 10% 的索引,可以根据需要调整参数。

select p.table_schema, p.table_name, c.index_name, c.car, p.car total from
       (select table_schema, table_name, index_name, max(cardinality) car
         from INFORMATION_SCHEMA.STATISTICS
     where index_name != ‘PRIMARY‘
     group by table_schema, table_name,index_name) c,
       (select table_schema, table_name, max(cardinality) car
         from INFORMATION_SCHEMA.STATISTICS
     where index_name = ‘PRIMARY‘ and table_schema != ‘mysql‘
     group by table_schema,table_name) p
     where c.table_name = p.table_name and c.table_schema = p.table_schema and p.car > 0 and c.car / p.car < 0.1;

结果:

4. 复合主键

由于 innodb 是聚簇表,每个二级索引都会包含主键值。复合主键会造成二级索引庞大,而影响二级索引查询性能,并影响更新性能。同样需要根据实际情况进一步分析。

sql 为:

select table_schema, table_name, group_concat(column_name order by seq_in_index separator ‘,‘) cols, max(seq_in_index) len
        from INFORMATION_SCHEMA.STATISTICS
        where index_name = ‘PRIMARY‘ and table_schema != ‘mysql‘
        group by table_schema, table_name having len>1;

结果为:

时间: 2025-01-14 01:44:36

MySQL 重复索引探讨(持续更新中...)的相关文章

Mysql注入小tips --持续更新中

学习Web安全好几年了,接触最多的是Sql注入,一直最不熟悉的也是Sql注入.OWASP中,Sql注入危害绝对是Top1.花了一点时间研究了下Mysql类型的注入. 文章中的tips将会持续更新,先说说这些天研究的 这里博主以数字类型注入类型进行讲解,字符类型同理,这里不在敖述. 我们的环境:phpstudy+mysql+php 我们的测试代码如下: <meta http-equiv="Content-Type" content="text/html; charset=

MySQL数据库知识点整理 (持续更新中)

一.修改用户密码 格式(在命令行下输入):mysqladmin -u 用户名 -p旧密码 password 新密码 1. 给root添加密码ab12:  mysqladmin -uroot -password ab12 2. 将root的密码修改为djg345:    mysqladmin -uroot -pab12 password djg345 二.添加新用户 格式:grant 权限 on 数据库名.表名 to 用户名@登录主机  identified by "密码" 1. 增加一

【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包含:数组类.浏览器类.日期类.函数类.数学类.媒体类.节点类.对象类.字符串类.类型检测类.正则表达式类等内容. 使用方法 1. 引入Bable transpiler以保证支持ES6 <script type="javascript/text" src="./browser

MySQL乱码收集_持续更新

1.在mysql中执行下句成功,可添加中文的. insert into book(bookName,author,publish) values('好','hao','hao'); 但是在jsp中执行这个insert 语句就会出现乱码. 解决方案:在url后面加上?useUnicode=true&characterEncoding=utf-8 2.导入txt文件中的sql语句,乱码. 先是执行show variables like '%char%'; +---------------------

前端面试题总结——Html5(持续更新中)

前端面试题总结--H5(持续更新中) 1.HTML5 为什么只需要写 <!DOCTYPE HTML>? HTML5 需要doctype来规范浏览器的行为,让浏览器按照它们应该的方式来运行:HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型. 2.HTML5的form如何关闭自动完成功能? 给不想要提示的 form 或某个 input 设置为 autocomplete=off. 3.HTML5 中如何嵌入音频? 当前,audio 元素支持三种音频格式:&l

linux学习资料持续更新中

一.LINUX基础教程 1.老男孩系列免费视频: 1) linux高薪入门实战视频教程(第二部)老男孩linux教程 http://edu.51cto.com/course/course_id-1035-page-1.html 2) 跟着老男孩从0开始一步步实战深入学习linux运维(三) http://edu.51cto.com/lesson/id-11909.html linux学习资料持续更新中,布布扣,bubuko.com

Hello World!的各种编程语言程序(持续更新中……)

对于很多学习编程语言新手们,可能接触到的第一个程序就是"Hello World"的输出程序,笔者想在此篇简短的博文中介绍关于各种编程语言的"Hello World"输出程序. 至今,笔者仅仅接触过C++和Python两种编程语言,而且都仅仅是新手,所以此次只能写C++和Python两种语言的"Hello World"输出程序,但此篇博文会随着笔者学习的编程语言种类的增多而不断完善. 1. C++语言 #include<iostream>

阿里笔试题(2015)持续更新中

第一次做阿里笔试题,除了ACM题之外从来没有做过校招网络题呀,完全是裸考,总体感觉吧,对于我来说,感觉时间不够用,不是题不会,感觉时间紧,大脑很混乱,总结这一次的笔试题 废话不多说,直接上题和答案 平均每个人逗留时间为20分钟,那么开场前20分钟一共来了400人,且有20个人逗留时间已经到,但他们不一定出去,注意是平均时间,所有博物馆最少应该容纳500人 双向循环列表,从任何一个元素开始可以遍历全部元素 先和后面的元素相连 s->next=p->next; p->next->pre

Atom使用记录(持续更新中)

部分内容取自:http://www.jianshu.com/p/dd97cbb3c22d,我自己也在使用,持续更新中 Atom安装插件在窗口中File---Setting---install 在里面进行搜索就行. minimap: 为Atom加上一个代码预览地图,就想sublime中右侧的缩略图一样,效果如图. Emmet(和sublime一样的) simplified-chinese-menu:Atom的简体中文语言包,完整汉化,兼容所有已发布的版本Atom. autoclose-html:h