• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > MySQL的聚簇索引、非聚簇索引及其查询解析方法

MySQL的聚簇索引、非聚簇索引及其查询解析方法

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-05

匿名通过本文主要向大家介绍了MySQL,聚簇索引,非聚簇索引等相关知识,希望本文的分享对您有所帮助
1.聚簇索引和非聚簇索引

索引是用来提高数据库性能的,用于快速找出某个列中有一特定值的行,如果不使用索引,MySQL必须从第1条记录开始读完整个表直到找出相关的行,表越大,花费的时间越多,如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜索数据文件,没有必要看全部数据,这对性能将有极大的提升。

再用一道数据题来理解:如果表中的一条记录在磁盘上占用 1000字节的话,我们对其中10字节的一个字段建立索引,那么该记录对应的索引块的大小只有10字节。我们知道,MySQL的最小空间分配单元是“页(Page)”,一个页在磁盘上默认占用16K空间,那么这一个页可以存储上述记录16条,但可以存储索引1600条。现在我们要从一个有16000条记录的表中检索符合某个条件的记录,如果没有索引的话,我们可能需要遍历16000条×1000字节/16K字节=1000个页面才能够找到结果。如果在检索字段上有上述索引的话,那么我们可以在16000条×10字节/16K字节=10个页面中就检索到满足条件的索引块,然后根据索引块上的指针逐一找到结果数据块,这样IO访问量要少的多,可见索引对性能的提升作用。

索引可分为聚簇索引和非聚簇索引。

聚簇索引中键值的逻辑顺序决定了表数据行的物理顺序,只要索引是相邻的,对应的数据一定也是相邻地存放在磁盘上,因此每张表只能建立一个聚簇索引。比如英语课本中查找某个单词在第8页,翻到第6页再往后翻,翻到第10页再往前翻,这就类似于聚簇索引,表存储数据的顺序就是跟着聚簇索引来存储的。

InnoDB表中聚簇索引首选主键,其次选择不含null值的唯一索引,如果两者都无,则会内置rowid作为隐含的聚集索引。

官方文档关于这个知识点描述如下:

? When you define a PRIMARY KEY on your table, InnoDB uses it as theclustered index.Define a primary key for each table that you create. If there is no logicalunique and non-null column or set of columns, add a new auto-increment column, whose values are filled in automatically. 首选主键

? If you do not define a PRIMARY KEY for your table, MySQL locates thefirst UNIQUE index where all the key columns are NOT NULL and InnoDB uses it asthe clustered index. 没有主键则选非空唯一索引

? If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDBinternally generates a hidden clustered index on a synthetic column containingrow ID values. The rows are ordered by the ID that InnoDB assigns to the rowsin such a table. The row ID is a 6-byte field that increases monotonically asnew rows are inserted. Thus, the rows ordered by the row ID are physically ininsertion order.都没有的话就内置rowid生成隐含的聚集索引

非聚簇索引中键值的逻辑顺序与数据行的物理存储顺序不同,假设要找某个单词,需要翻到英语书后面的单词目录,找到对应的字母位置,看其所在第几课,然后再找到对应课中的单词。这个附录就类似非聚簇索引。一个表可以有不止一个非聚簇索引,非聚簇索引需要大量的硬盘空间和内存,虽然非聚簇索引可以提高从表中读取数据的速度,但也会降低向表中插入和更新数据的速度,因为只要你更新一个建立了非聚簇索引的表中的数据时,必须要同时更新索引。

一般缺省情况下建立的索引是非聚簇索引,但并一定是最佳的,因为很多情况下,聚簇索引比非聚簇索引查询效率高很多,聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有一个指针指向对应的数据块。而且如果需要频繁地更新表数据就不要建太多非聚簇索引,另外,如果硬盘和内存空间有限,也应该限制非聚簇索引的数量。总之,真正合理的索引设计要建立在对各种查询的分析和预测上。

官方文档说明如下:

Every InnoDB table has aspecial index called the clustered index where the data for the rows is stored. 
Typically, the clustered indexis synonymous with the primary key. 
To get the best performance from queries, inserts, and other databaseoperations, you must understand how InnoDB uses the clustered 
index to optimizethe most common lookup and DML operations for each table.


2.如何查询表的索引基本情况?

表的索引情况记录在information_schema库中的statistics表中,该表专提供表索引的信息,查询某库某表索引信息语句如下:

SELECT * FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'tbl_name'
AND table_schema = 'db_name'

或者

SHOW INDEX FROM tbl_name FROM db_name


指定查询某库某表索引情况的语句:

mysql> select * from statistics whereTABLE_SCHEMA='cloudXXX' and TABLE_NAME='opmXXXX'\G

查询第一行数据进行逐个字段解析:

mysql> select * fromstatistics limit 0,1\G

*************************** 1. row ***************************

TABLE_CATALOG: def 数据表登记目录

TABLE_SCHEMA: monitor_XXXX 索引所属表的数据库名

TABLE_NAME: alarm_XXXX 索引所属的数据表名

NON_UNIQUE: 0 字段不唯一的标识,索引不能包括重复词则为0,否则为1

INDEX_SCHEMA: monitor_XXXX 索引所属的数据库名

INDEX_NAME: PRIMARY 索引名称,primary一般是聚簇索引

SEQ_IN_INDEX: 1 索引中的序列号,从1开始

COLUMN_NAME: id 索引列的列名

COLLATION: A 校对,列值全显示为A

CARDINALITY: 58 基数,同该表的数据行数

SUB_PART: NULL 列只是部分编入索引,则显示编入索引的字符的数据,如整列被编入索引,则为NULL

PACKED: NULL 关键字是否包装过,没有压缩包装则默认为NULL

NULLABLE: 是否为空

INDEX_TYPE: BTREE 索引的类型,列值全显示为BTREE,InnoDB的存储引擎默认创建的是BTREE(举例:BTREE,FULLTEXT, HASH, RTREE)

COMMENT: 索引注释、备注

INDEX_COMMENT:

如果查询某库某表索引信息没有任何输出,则说明该表未建索引。

3.如何查询表的索引类型情况?

InnoDB表的索引类型情况在information_schema库中的INNODB_SYS_TABLES和INNODB_SYS_INDEXES里。

先在INNODB_SYS_TABLES表里找到自己需要查询的表对应的TABLE_ID:

mysql> select TABLE_ID,NAME from INNODB_SYS_TABLESwhere NAME like 'monitor %';

输出举例:

|       76 |monitor_XXXXXXXX/os_perf_biz_vpn                          |
|       77 |monitor_ XXXXXXXX /os_perf_biz_vpn_day                      |
|       78 |monitor_ XXXXXXXX /os_perf_biz_vpn_hour                     |
|       79 |monitor_ XXXXXXXX /os_perf_biz_vpn_month                    |

再用这个TABLE_ID去INNODB_SYS_INDEXES表里去查该表的索引类型:

mysql> select * from INNODB_SYS_INDEXES whereTABLE_ID between '76' and '199';

输出举例:

+----------+-------------------+----------+------+----------+---------+-------+
| INDEX_ID | NAME              | TABLE_ID | TYPE | N_FIELDS |PAGE_NO | SPACE |
+----------+-------------------+----------+------+----------+---------+-------+
|       92 | GEN_CLUST_INDEX   |      76 |    1 |        0 |       3 |   65 |
|      351 | create_time_index |       76 |   0 |        1 |       4 |   65 |
|       93 | GEN_CLUST_INDEX   |      77 |    1|        0 |       3 |   66 |
|      352 | create_time_index |       77 |   0|        1 |       4 |   66

这个输出关键看TYPE字段,TYPE字段官网解析如下:

A numeric identifiersignifying the kind of index. 
0 = Secondary Index, 
1 =Clustered Index, 
2 = Unique Index, 
3 = PrimaryIndex, 
32 = Full-text Index, 
64 = Spatial Index, 
128 = A secondary indexthat includes a generated virtual column

TYPE为0便是辅助索引,也是非聚簇索引,1是聚簇索引,3是主键索引。上文输出可以看出这些表建的就是非聚簇索引,索引名字为create_time_index。

除此之外,还有个GEN_CLUST_INDEX,其官网解析如下:

If the name isGEN_CLUST_INDEX, the index is the clustered index thatis created automatically if the table definition doesn't include a primary keyor non-NULL unique index.

即使一个既无主键也无索引的表,在statistics中没有任何记录,在这里也可以查询如下,这也应证了上文所述的InnoDB表隐含的聚集索引:

mysql>select TABLE_ID,NAME from INNODB_SYS_TABLES where NAME='monitor_XXXXXX/os_XXXXXX';
+----------+---------------------------------------------------+
|TABLE_ID | NAME                                              |
+----------+-------------------------
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 分享下mysql各个主要版本之间的差异
  • MySQL essential版本和普通版本有什么区别?
  • redhat 5.4下安装MYSQL全过程
  • 如何用SQL命令查看Mysql数据库大小
  • 解析mysql中如何获得数据库的大小
  • 解析mysql修改为utf8后仍然有乱码的问题
  • 5个常用的MySQL数据库管理工具详细介绍
  • 解析在MySQL里创建外键时ERROR 1005的解决办法
  • 解析远程连接管理其他机器上的MYSQL数据库
  • mysql 精简过程(删除一些文件)

相关文章

  • 2018-12-05MySQL Cluster集群配置方案
  • 2018-12-05win7安装oracle10g 提示程序异常终止 发生未知错误
  • 2018-12-05有关误删表的课程推荐
  • 2017-05-11mysql 导入导出数据库、数据表的方法
  • 2017-05-11分析MySQL中索引引引发的CPU负载飙升的问题
  • 2017-05-11mysql触发器(Trigger)简明总结和使用实例
  • 2017-05-11mysql error:#1062 Duplicate entry ‘***′ for key 1问题解决方法
  • 2018-12-05sqlserver通用的删除服务器上的所有相同后缀的临时表
  • 2017-05-11mysql修改用户密码的方法和mysql忘记密码的解决方法
  • 2018-12-05mysql备份恢复mysqldump.exe几个常用用例

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • sqlserver replace函数 批量替换数据库中指定字段内指定字符串参
    • myeclipse连接MySQL数据库详细步骤
    • PL/SQL编程经验小结开发者网络Oracle
    • MySQL如何设置远程连接数据库?
    • 当恢复sqlserver bak文件时,原始的用户无法删除的解决方法
    • MySQL数据库与表的最基本命令大盘点
    • 一个效率很高的汉字转拼音首字母的函数
    • MySQL5.7.10解压版详细安装教程
    • MySQL如何正确地利用AES_ENCRYPT()与AES_DECRYPT()加解密
    • 数据库优化实践【TSQL篇】

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有