查看表主键信息

## 查看表主键信息
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引擎的主键索引的更多相关文章

  1. mysql的innodb自增主键为什么不是连续的

    图1 图1中是表t原有的数据,这个时候我们执行show create table t会看到如下输出,如图二所示现在的自增值是2,也就是下一个不指定主键值的插入的数据的主键就是2 图2 Innodb引擎 ...

  2. 修改mysql表结构,添加一个主键索引自增字段,修改原来的主字段为普通字段

    原来有一个字段id,为自增,主键,索引.现在要新增一个字段s_id为自增,主键,索引.同时把原来的主字段改成普通字段,默认值为0. Alter table e_diamond_jhds change ...

  3. 聚集索引、非聚集索引、聚集索引组织表、堆组织表、Mysql/PostgreSQL对比、联合主键/自增长、InnoDB/MyISAM(引擎方面另开一篇)

    参考了多篇文章,分别记录,如下. 下面是第一篇的总结 http://www.jb51.net/article/76007.htm: 在MySQL中,InnoDB引擎表是(聚集)索引组织表(cluste ...

  4. mysql死锁-非主键索引更新引起的死锁

    背景:最近线上经常抛出mysql的一个Deadlock,细细查来,长了知识! 分析:错误日志如下: 21:02:02.563 ERROR dao.CommonDao        [pool-15-t ...

  5. Mysql索引介绍及常见索引(主键索引、唯一索引、普通索引、全文索引、组合索引)的区别

    Mysql索引概念:说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不是越多越好,假如这本书1000页,有500也是目录,它当然效率低,目录是要 ...

  6. MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析

    文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...

  7. Mysql主键索引、唯一索引、普通索引、全文索引、组合索引的区别

    原文:Mysql主键索引.唯一索引.普通索引.全文索引.组合索引的区别 Mysql索引概念: 说说Mysql索引,看到一个很少比如:索引就好比一本书的目录,它会让你更快的找到内容,显然目录(索引)并不 ...

  8. mysql索引之主键索引

    MySQL目前主要有以下几种索引类型:1.普通索引2.唯一索引3.主键索引4.组合索引5.全文索引 二.语句 CREATE TABLE table_name[col_name data type] [ ...

  9. 一分钟掌握MySQL的InnoDB引擎B+树索引

    MySQL的InnoDB索引结构采用B+树,B+树什么概念呢,二叉树大家都知道,我们都清楚随着叶子结点的不断增加,二叉树的高度不断增加,查找某一个节点耗时就会增加,性能就会不断降低,B+树就是解决这个 ...

随机推荐

  1. openresty开发系列32--openresty执行流程之1初始化阶段

    openresty开发系列32--openresty执行流程之初始化阶段 一)初始化阶段 1)init_by_lua   init_by_lua_block     init_by_lua_file语 ...

  2. [简短问答]LODOP打印不清晰

    用什么语句输出的:使用的的是什么语句输出的,是ADD_PRINT_TEXT纯文本,还是html的超文本. 超文本不清晰:如果用的是ADD_PRINT_HTML ,换成 ADD_PRINT_HTM试试, ...

  3. [LeetCode] 310. Minimum Height Trees 最小高度树

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  4. 【视频开发】【Live555】通过live555实现H264 RTSP直播

    前面的文章中介绍了<H264视频通过RTMP流直播>,下面将介绍一下如何将H264实时视频通过RTSP直播. 实现思路是将视频流发送给live555, 由live555来实现H264数据流 ...

  5. servlet 读取文件

    读取pdf protected void service(HttpServletRequest request, HttpServletResponse response) throws Servle ...

  6. 【转】Fuel-Openstack的搭建(一)

    原文链接:https://blog.csdn.net/qq_35180983/article/details/82181496 2.1安装前的准备操作: 首先,我们需要准备以下操作: 2.1.1 下载 ...

  7. 面试官:知道你的接口QPS是多少么?(转)

    面试官:知道你的接口QPS是多少么? 原创: 孤独烟 孤独烟 9月24日 引言 大家好,我是渣渣烟. 我又来水文章了.这篇文章我个人感觉含金量不是太大,大概5分钟左右就能看完!其实大家都知道,我不爱写 ...

  8. [hdu 4841]圆桌问题 | 约瑟夫问题 STL-vector

    原题 问题描述: 经典的约瑟夫问题,有2n个人,其中n个好人n个坏人,使得删去n人后,剩下的全为好人.m为每次数的人数. n<=32767 题解: 首先考虑n的范围,暴力肯定行不通,所以会想到线 ...

  9. Java开发笔记(一百二十一)AWT输入框

    前面介绍了文本标签Label,该控件展示的文字是不可编辑的,若要用户在界面上输入文本,就得使用专门的编辑框控件.在AWT的控件家族当中,用作编辑框的有两种控件,分别是单行输入框TextField和多行 ...

  10. fwrite & fread 的使用

    每一次切换文件操作模式必须调用fclose关闭文件. 如果直接切换操作模式,文件将损坏(出现乱码)或操作失败. 在调用了fclose时,作为参数的文件指针将被回收,必须再次定义,因此最好将功能封装. ...