为了演示,首先建两个包含不良索引的表,并弄点数据。

  1. mysql> show create table test1\G
  2. *************************** 1. row ***************************
  3. Table: test1
  4. Create Table: CREATE TABLE `test1` (
  5. `id` int(11) NOT NULL,
  6. `f1` int(11) DEFAULT NULL,
  7. `f2` int(11) DEFAULT NULL,
  8. `f3` int(11) DEFAULT NULL,
  9. PRIMARY KEY (`id`),
  10. KEY `k1` (`f1`,`id`),
  11. KEY `k2` (`id`,`f1`),
  12. KEY `k3` (`f1`),
  13. KEY `k4` (`f1`,`f3`),
  14. KEY `k5` (`f1`,`f3`,`f2`)
  15. ) ENGINE=InnoDB DEFAULT CHARSET=latin1
  16. 1 row in set (0.00 sec)
  17. mysql> show create table test2\G
  18. *************************** 1. row ***************************
  19. Table: test2
  20. Create Table: CREATE TABLE `test2` (
  21. `id1` int(11) NOT NULL DEFAULT '0',
  22. `id2` int(11) NOT NULL DEFAULT '0',
  23. `b` int(11) DEFAULT NULL,
  24. PRIMARY KEY (`id1`,`id2`),
  25. KEY `k1` (`b`)
  26. ) ENGINE=InnoDB DEFAULT CHARSET=latin1
  27. 1 row in set (0.00 sec)
  28. mysql> select count(*) from test2 group by b;
  29. +----------+
  30. | count(*) |
  31. +----------+
  32. | 32 |
  33. | 17 |
  34. +----------+
  35. 2 rows in set (0.00 sec)

1. 包含主键的索引

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

  1. mysql> select c.*, pk from
  2. -> (select table_schema, table_name, index_name, concat('|', group_concat(column_name order by seq_in_index separator '|'), '|') cols
  3. -> from INFORMATION_SCHEMA.STATISTICS
  4. -> where index_name != 'PRIMARY' and table_schema != 'mysql'
  5. -> group by table_schema, table_name, index_name) c,
  6. -> (select table_schema, table_name, concat('|', group_concat(column_name order by seq_in_index separator '|'), '|') pk
  7. -> from INFORMATION_SCHEMA.STATISTICS
  8. -> where index_name = 'PRIMARY' and table_schema != 'mysql'
  9. -> group by table_schema, table_name) p
  10. -> where c.table_name = p.table_name and c.table_schema = p.table_schema and c.cols like concat('%', pk, '%');
  11. +--------------+------------+------------+---------+------+
  12. | table_schema | table_name | index_name | cols | pk |
  13. +--------------+------------+------------+---------+------+
  14. | test | test1 | k1 | |f1|id| | |id| |
  15. | test | test1 | k2 | |id|f1| | |id| |
  16. +--------------+------------+------------+---------+------+
  17. 2 rows in set (0.04 sec)

2. 重复索引前缀

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

  1. mysql> select c1.table_schema, c1.table_name, c1.index_name,c1.cols,c2.index_name, c2.cols from
  2. -> (select table_schema, table_name, index_name, concat('|', group_concat(column_name order by seq_in_index separator '|'), '|') cols
  3. -> from INFORMATION_SCHEMA.STATISTICS
  4. -> where table_schema != 'mysql' and index_name!='PRIMARY'
  5. -> group by table_schema,table_name,index_name) c1,
  6. -> (select table_schema, table_name,index_name, concat('|', group_concat(column_name order by seq_in_index separator '|'), '|') cols
  7. -> from INFORMATION_SCHEMA.STATISTICS
  8. -> where table_schema != 'mysql' and index_name != 'PRIMARY'
  9. -> group by table_schema, table_name, index_name) c2
  10. -> 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;
  11. +--------------+------------+------------+------------+------------+---------+
  12. | table_schema | table_name | index_name | cols | index_name | cols |
  13. +--------------+------------+------------+------------+------------+---------+
  14. | test | test1 | k1 | |f1|id| | k3 | |f1| |
  15. | test | test1 | k4 | |f1|f3| | k3 | |f1| |
  16. | test | test1 | k5 | |f1|f3|f2| | k3 | |f1| |
  17. | test | test1 | k5 | |f1|f3|f2| | k4 | |f1|f3| |
  18. +--------------+------------+------------+------------+------------+---------+
  19. 4 rows in set (0.02 sec)

3. 低区分度索引

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

  1. mysql> select p.table_schema, p.table_name, c.index_name, c.car, p.car total from
  2. -> (select table_schema, table_name, index_name, max(cardinality) car
  3. -> from INFORMATION_SCHEMA.STATISTICS
  4. -> where index_name != 'PRIMARY'
  5. -> group by table_schema, table_name,index_name) c,
  6. -> (select table_schema, table_name, max(cardinality) car
  7. -> from INFORMATION_SCHEMA.STATISTICS
  8. -> where index_name = 'PRIMARY' and table_schema != 'mysql'
  9. -> group by table_schema,table_name) p
  10. -> 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;
  11. +--------------+------------+------------+------+-------+
  12. | table_schema | table_name | index_name | car | total |
  13. +--------------+------------+------------+------+-------+
  14. | test | test2 | k1 | 4 | 49 |
  15. +--------------+------------+------------+------+-------+
  16. 1 row in set (0.04 sec)

4. 复合主键

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

  1. mysql> select table_schema, table_name, group_concat(column_name order by seq_in_index separator ',') cols, max(seq_in_index) len
  2. -> from INFORMATION_SCHEMA.STATISTICS
  3. -> where index_name = 'PRIMARY' and table_schema != 'mysql'
  4. -> group by table_schema, table_name having len>1;
  5. +--------------+------------+-----------------------------------+------+
  6. | table_schema | table_name | cols | len |
  7. +--------------+------------+-----------------------------------+------+
  8. | test | test2 | id1,id2 | 2 |
  9. +--------------+------------+-----------------------------------+------+
  10. 1 rows in set (0.01 sec)
  11. 本文来自云栖社区合作伙伴“Linux中国”,原文发布日期:2015-08-18

找到 mysql 数据库中的不良索引相关推荐

  1. 【转】找到 MySQL 数据库中的不良索引

    为了演示,首先建两个包含不良索引的表,并弄点数据. mysql> show create table test1/G *************************** 1. row *** ...

  2. MySQL数据库中的索引(含SQL语句)

    文章目录 为什么要用索引 索引是什么 索引的原理 优点 缺点 创建索引的原则 什么情况下需要索引 什么情况下不需要索引 索引的分类 主键索引 单值索引 唯一索引 组合索引(复合索引) 全文索引(仅在M ...

  3. B+树:MySQL数据库中建立索引的数据结构

    在MySQL数据库中是通过B+树的数据结构建立索引的. 相比二叉树,B树是一种多叉树,总层数更少,磁盘io次数也会相应减少.而与B树不同的是,B+树把索引和数据分开存储,数据以链表的形式存放在B+树的 ...

  4. MySQL数据库的数据类型和索引

    数据库的数据库索引对程序员来说是透明的,意味着数据库建立索引之前和之后,你的SQL语句都可以正常运行,索引的运用只是数据库引擎工作时候的优化手段.但是,这不是意味着数据库索引仅仅是数据库设计和运维者的 ...

  5. bd2和mysql语法区别,经验:在MySQL数据库中,这4种方式可以避免重复的插入数据!...

    最常见的方式就是为字段设置主键或唯一索引,当插入重复数据时,抛出错误,程序终止,但这会给后续处理带来麻烦,因此需要对插入语句做特殊处理,尽量避开或忽略异常,下面我简单介绍一下,感兴趣的朋友可以尝试一下 ...

  6. 在MySQL数据库中,这4种方式可以避免重复的插入数据!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:小小猿爱嘻嘻 wukong.com/question/674 ...

  7. 查看MYSQL数据库中所有用户及拥有权限

    查看MYSQL数据库中所有用户 mysql> SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM m ...

  8. MySQL数据库中常见的日志文件汇总!

    一个优秀的Java后端开发工程师一定要掌握MySQL数据库,而日志文件记录了影响MySQL数据库的各种类型活动,因此也成为其必须要掌握的知识.今天千锋ava培训小编就给大家介绍MySQL数据库中常见的 ...

  9. Python3调用MySQL数据库中的数据

    在学习<Designing Machine Learning Systems with Python>(中文名<机器学习系统设计--Python语言实现>)一书中,在第三章第二 ...

最新文章

  1. .NET/C#中对自定义对象集合进行自定义排序的方法
  2. 真实案例引起的对系统健壮性的思考
  3. Matlab Tricks(二十九) —— 使用 deal 将多个输入赋值给多个输出
  4. Python——列表中存放字典遇到的问题
  5. 为了适应云数据库mySQL产品_为了适应不同的应用场景,云数据库mysql版提供的产品系列包括哪些...
  6. Linux单独编译设备树,迅为IMX6Q开发板-非设备树内核-单独编译内核驱动
  7. 【转载】送到榨油厂的飞鸽传书
  8. javascript 用函数语句和表达式定义函数的区别详解
  9. 这个高仿真框架AI2-THOR,想让让强化学习快速走进现实世界
  10. R语言中文社区2018年终文章整理(类型篇)
  11. C# Lamda中类似于SQL 中的 In 功能
  12. 数值计算详细笔记(二):非线性方程解法
  13. python识别图片文字、并返回文字坐标_简易OCR图片文字识别工具的进一步改进(增加显示图片的功能)...
  14. CUDA的下载与安装
  15. android完全关闭应用程序,安卓手机后台程序不能彻底关闭?试试这个强制关闭的功能!...
  16. 罗马数字转换阿拉伯数字
  17. 用Maple求偏导数
  18. 千粉缔造760w播放!B站“新人”UP主在B站怎么加速上位?
  19. docker容器启动成功外界却无法访问
  20. 请你用严谨的数学语言证明一下庞加莱猜想

热门文章

  1. android 验证输入,最佳实践:输入验证(Android)
  2. python语言:烟花效果实现
  3. linux dns中文域名,Nginx 中文域名配置详解及实现
  4. java aes key iv_java – AES / CBC真的需要IV参数吗?
  5. php系统升级说明,PHPCMF内容管理框架 v4.2.7 升级说明
  6. netstat和lsof端口结果不一致
  7. 求两个集合的差集代码_求求你了,不要再写循环求两个列表的交集,并集和差集了 | pythonic 小技巧...
  8. ext store 数据修改_Go 数据存储篇(一):基于内存存储实现数据增删改查功能...
  9. 浏览器直接连接mysql_在IE中直接连接SQL数据库_MySQL
  10. 关于MySQL二次安装问题