MySQL Index--InnoDB引擎的主键索引
查看表主键信息
- ## 查看表主键信息
- SELECT
- t.TABLE_NAME,
- t.CONSTRAINT_TYPE,
- c.COLUMN_NAME,
- c.ORDINAL_POSITION
- FROM
- INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS t,
- INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS c
- WHERE
- t.TABLE_NAME = c.TABLE_NAME
- AND t.CONSTRAINT_TYPE = 'PRIMARY KEY'
- AND t.TABLE_NAME='<TABLE_NAME>'
- AND t.TABLE_SCHEMA='<TABLE_SCHEMA>';
查看无主键表
- ## 查看无主键表
- SELECT table_schema, table_name,TABLE_ROWS
- FROM information_schema.tables
- WHERE (table_schema, table_name) NOT IN (
- SELECT DISTINCT table_schema, table_name
- FROM information_schema.columns
- WHERE COLUMN_KEY = 'PRI'
- )
- AND table_schema NOT IN ('sys', 'mysql', 'information_schema', 'performance_schema');
无主键表
在Innodb存储引擎中,每张表都会有主键,数据按照主键顺序组织存放,该类表成为索引组织表 Index Ogranized Table
如果表定义时没有显示定义主键,则会按照以下方式选择或创建主键:
- a) 先判断表中是否有"非空的唯一索引",如果有
- ) 如果仅有一条"非空唯一索引",则该索引为主键
- ) 如果有多条"非空唯一索引",根据索引索引的先后顺序,选择第一个定义的非空唯一索引为主键。
- b) 如果表中无"非空唯一索引",则自动创建一个6字节大小的指针作为主键。
如果主键索引只有一个索引键,那么可以使用_rowid来显示主键,如:
- ## 删除测试表
- DROP TABLE IF EXISTS tb2001;
- ## 创建测试表
- CREATE TABLE `tb2001` (
- `id` int() NOT NULL,
- `c1` int() DEFAULT NULL,
- UNIQUE uni_id (id),
- INDEX idx_c1(c1)
- ) ENGINE = InnoDB CHARSET = utf8;
- ## 插入测试数据
- INSERT INTO tb2001 (id, c1)
- SELECT , ;
- INSERT INTO tb2001 (id, c1)
- SELECT , ;
- INSERT INTO tb2001 (id, c1)
- SELECT , ;
- ## 查看数据和_rowid
- SELECT *, _rowid
- FROM tb2001;
- +----+------+--------+
- | id | c1 | _rowid |
- +----+------+--------+
- | | | |
- | | | |
- | | | |
- +----+------+--------+
可以发现,上面的_rowid与id的值相同,因为id列是表中第一个唯一且NOT NULL的索引。
强制主键索引
由于主键索引只能为PRIMARY:
- SHOW INDEXES IN tb2001 \G
- *************************** . row ***************************
- Table: tb2001
- Non_unique:
- Key_name: PRIMARY
- Seq_in_index:
- Column_name: id
- Collation: A
- Cardinality:
- Sub_part: NULL
- Packed: NULL
- Null:
- Index_type: BTREE
- Comment:
- Index_comment:
因此在强制走主键索引FORCE INDEX(PRIMARY)时,使用:
- SELECT *
- FROM tb2001 FORCE INDEX(PRIMARY)
- WHERE C1=;
非聚集索引中的聚集索引键
在MySQL 5.6.9版本前,Innodb的非聚集索引中包含聚集索引的索引键,但只起到通过非聚集索引定位记录的作用,但在MySQL 5.6.9之后版本中,优化器会考虑非聚集索引中包含的聚集索引键来提升查询性能,并提供优化器选项use_index_extensions来开启或关闭该特性。
假设有表TB1(ID,C1,C2), ID为主键聚集索引,然后在列C1建立索引IDX_C1(C1):
在MySQL 5.6版本前,索引类似于IDX_C1(C1) INCLUDE(ID);
在MySQL 5.6版本中,索引类似于IDX_C1(C1,ID);
无论是MySQL 5.5还是MySQL 5.6版本中,非聚集索引上的数据都是先按照非聚集索引键在按照聚集索引键进行排序,即在非聚集索引键上值相同的记录会按照聚集索引进行排序。
对于查询:
- SELECT *
- FROM TB1
- WHERE C1='ABC'
- AND ID>
- AND ID<
在MySQL 5.5版本中,需要按照索引IDX_C1扫描所有C1='ABC'的记录,再根据ID进行过滤。
在MySQL 5.6版本中,进行按照索引IDX_C1就可以先定位C1='ABC' AND ID>10的第一条记录,再顺序扫描至C1='ABC' AND ID<1000的记录,有效减少扫描的数据量。
对于查询:
- SELECT *
- FROM TB1
- WHERE C1='ABC'
- ORDER BY ID
- LIMIT
如果满足C1='ABC'的记录数较多,那么查询在MySQL 5.5版本就会性能极差,而在MySQL 5.6版本中变得性能极好,MySQL 5.5版本可以将IDX_C1(C1)优化为 IDX(C1,ID)。
在MySQL 5.5.14版本进行测试,准备测试数据:
- ## 删除测试表
- DROP TABLE IF EXISTS tb2001;
- ## 创建测试表
- CREATE TABLE `tb2001` (
- `id` int() NOT NULL AUTO_INCREMENT PRIMARY KEY,
- `c1` int() DEFAULT NULL,
- `c2` int() DEFAULT NULL,
- INDEX idx_c1(c1),
- INDEX idx_c2(c2,id)
- ) ENGINE = InnoDB CHARSET = utf8;
- ## 插入测试数据(10万左右)
- ## 如果information_schema.columns数据较少,可以重复多次
- INSERT INTO tb2001 (c1,c2)
- SELECT , from information_schema.columns;
测试1:
- ## 测试SQL
- SELECT c1,id
- FROM tb2001 FORCE INDEX(idx_c1)
- WHERE C1= and id<;
- ## 执行时间超过20MS
- ## 对应执行计划为:
- *************************** . row ***************************
- id:
- select_type: SIMPLE
- table: tb2001
- type: ref
- possible_keys: idx_c1
- key: idx_c1
- key_len:
- ref: const
- rows:
- Extra: Using where; Using index
- ## 对应PROFILING数据为:
- +----------------------+----------+----------+------------+--------------+---------------+-------+
- | Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
- +----------------------+----------+----------+------------+--------------+---------------+-------+
- | starting | 0.000039 | 0.000000 | 0.000000 | | | |
- | checking permissions | 0.000007 | 0.000000 | 0.000000 | | | |
- | Opening tables | 0.000011 | 0.000000 | 0.000000 | | | |
- | System lock | 0.000008 | 0.000000 | 0.000000 | | | |
- | init | 0.000012 | 0.000000 | 0.000000 | | | |
- | optimizing | 0.000009 | 0.000000 | 0.000000 | | | |
- | statistics | 0.000041 | 0.000000 | 0.000000 | | | |
- | preparing | 0.000012 | 0.000000 | 0.000000 | | | |
- | executing | 0.000004 | 0.000000 | 0.000000 | | | |
- | Sending data | 0.020529 | 0.019997 | 0.000000 | | | |
- | end | 0.000006 | 0.000000 | 0.000000 | | | |
- | query end | 0.000004 | 0.000000 | 0.000000 | | | |
- | closing tables | 0.000006 | 0.000000 | 0.000000 | | | |
- | freeing items | 0.000020 | 0.000000 | 0.000000 | | | |
- | logging slow query | 0.000004 | 0.000000 | 0.000000 | | | |
- | cleaning up | 0.000004 | 0.000000 | 0.000000 | | | |
- +----------------------+----------+----------+------------+--------------+---------------+-------+
测试2:
- ## 测试SQL:
- SELECT c2,id
- FROM tb2001 FORCE INDEX(idx_c2)
- WHERE C2= and id<;
- ##执行时间2ms
- ## 对应执行计划为:
- *************************** . row ***************************
- id:
- select_type: SIMPLE
- table: tb2001
- type: range
- possible_keys: idx_c2
- key: idx_c2
- key_len:
- ref: NULL
- rows: 1
- Extra: Using where; Using index
- ## 对应PROFILING数据为:
- +----------------------+----------+----------+------------+--------------+---------------+-------+
- | Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
- +----------------------+----------+----------+------------+--------------+---------------+-------+
- | starting | 0.000042 | 0.000000 | 0.000000 | | | |
- | checking permissions | 0.000007 | 0.000000 | 0.000000 | | | |
- | Opening tables | 0.000012 | 0.000000 | 0.000000 | | | |
- | System lock | 0.000007 | 0.000000 | 0.000000 | | | |
- | init | 0.000012 | 0.000000 | 0.000000 | | | |
- | optimizing | 0.000008 | 0.000000 | 0.000000 | | | |
- | statistics | 0.000033 | 0.000000 | 0.000000 | | | |
- | preparing | 0.000011 | 0.000000 | 0.000000 | | | |
- | executing | 0.000004 | 0.000000 | 0.000000 | | | |
- | Sending data | 0.000031 | 0.000000 | 0.000000 | | | |
- | end | 0.000005 | 0.000000 | 0.000000 | | | |
- | query end | 0.000005 | 0.000000 | 0.000000 | | | |
- | closing tables | 0.000006 | 0.000000 | 0.000000 | | | |
- | freeing items | 0.000022 | 0.000000 | 0.000000 | | | |
- | logging slow query | 0.000004 | 0.000000 | 0.000000 | | | |
- | cleaning up | 0.000004 | 0.000000 | 0.000000 | | | |
- +----------------------+----------+----------+------------+--------------+---------------+-------+
参考链接:https://dev.mysql.com/doc/refman/5.6/en/index-extensions.html
MySQL Index--InnoDB引擎的主键索引的更多相关文章
- mysql的innodb自增主键为什么不是连续的
图1 图1中是表t原有的数据,这个时候我们执行show create table t会看到如下输出,如图二所示现在的自增值是2,也就是下一个不指定主键值的插入的数据的主键就是2 图2 Innodb引擎 ...
- 修改mysql表结构,添加一个主键索引自增字段,修改原来的主字段为普通字段
原来有一个字段id,为自增,主键,索引.现在要新增一个字段s_id为自增,主键,索引.同时把原来的主字段改成普通字段,默认值为0. Alter table e_diamond_jhds change ...
- 聚集索引、非聚集索引、聚集索引组织表、堆组织表、Mysql/PostgreSQL对比、联合主键/自增长、InnoDB/MyISAM(引擎方面另开一篇)
参考了多篇文章,分别记录,如下. 下面是第一篇的总结 http://www.jb51.net/article/76007.htm: 在MySQL中,InnoDB引擎表是(聚集)索引组织表(cluste ...
- mysql死锁-非主键索引更新引起的死锁
背景:最近线上经常抛出mysql的一个Deadlock,细细查来,长了知识! 分析:错误日志如下: 21:02:02.563 ERROR dao.CommonDao [pool-15-t ...
- Mysql索引介绍及常见索引(主键索引、唯一索引、普通索引、全文索引、组合索引)的区别
Mysql索引概念:说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不是越多越好,假如这本书1000页,有500也是目录,它当然效率低,目录是要 ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- Mysql主键索引、唯一索引、普通索引、全文索引、组合索引的区别
原文:Mysql主键索引.唯一索引.普通索引.全文索引.组合索引的区别 Mysql索引概念: 说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不 ...
- mysql索引之主键索引
MySQL目前主要有以下几种索引类型:1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引 二.语句 CREATE TABLE table_name[col_name data type] [ ...
- 一分钟掌握MySQL的InnoDB引擎B+树索引
MySQL的InnoDB索引结构采用B+树,B+树什么概念呢,二叉树大家都知道,我们都清楚随着叶子结点的不断增加,二叉树的高度不断增加,查找某一个节点耗时就会增加,性能就会不断降低,B+树就是解决这个 ...
随机推荐
- 如何打开uboot的函数debug()的开关,输出更多调试信息?
答: 有两种方法: 一. 方法一 在文件<file>.c的首行加入以下内容: #define DEBUG #undef CONFIG_LOGLEVEL #define CONFIG_LOG ...
- Xamarin图表开发基础教程(11)OxyPlot框架支持的图表类型
Xamarin图表开发基础教程(11)OxyPlot框架支持的图表类型 OxyPlot组件中支持7种类型的条型图表,分别为普通条形图.线型条形图.矩形条形图.差值图.龙卷风图.普通柱形图和柱形误差图, ...
- Hive Authorization
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Authorization https://www.cloudera.c ...
- Swift编码总结6
1.UILabel的minimumScaleFactor: 需要UIlabel根据字数多少来减小字体大小,使得UIlabel能够显示全所有的文字.你需要做的就是设置minimumScaleFactor ...
- 【Shell常用命令一】echo bash alias history 输出重定向 快捷键
echo输出命令 echo [选项] [输出内容] -e : 支持反斜线控制的字符转换 赋予执行权限 直接运行 chmond 755 hello.sh ./hello.sh 通过bash调用执行脚本 ...
- [LeetCode] 516. Longest Palindromic Subsequence 最长回文子序列
Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...
- Jenkins - 参数化构建
1 - 设置 根据输入的参数来执行不同的构建过程. 参数TIME作为环境变量,可以被引用. 项目的首页会出现" Build with Parameters"功能链接,没有了&quo ...
- python:单元测试框架pytest的一个简单例子
之前一般做自动化测试用的是unitest框架,发现pytest同样不错,写一个例子感受一下 test_sample.py import cx_Oracle import config from sen ...
- Spring boot后台搭建一使用MyBatis集成Mapper和PageHelper
目标: 使用 Spring boot+MyBatis+mysql 集成 Mapper 和 PageHelper,实现基本的增删改查 先建一个基本的 Spring Boot 项目开启 Spring B ...
- .Net Core 2.0发布到 CentOS
上一篇 在CentOS 7中 使用 Nginx 反代 .Net Core 中创建的项目是创建的默认项目,现在我们来将我们开发的项目发布到 CentOs 中,反代还是使用 Nginx 1.创建一个 .N ...