首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL中的聚类索引

MySQL中的聚类索引
EN

Stack Overflow用户
提问于 2018-12-19 19:32:31
回答 3查看 1.7K关注 0票数 3

我正在学习数据库中的索引。根据GeeksforGeeks (https://www.geeksforgeeks.org/indexing-in-databases-set-1/),为聚集索引创建索引文件。有一个图表显示有1-8学期的索引文件.

但是在阅读https://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key的时候,我们提到了

如果表有聚集索引,它基本上意味着索引就是表。

我想知道是否在聚集索引和非聚集索引中生成索引文件?

另外,我们能否看到表上的索引文件,即它存储了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-12-19 20:13:10

MySQL基本上只有一种索引方法: BTree。(是的,也有空间和全文,但这是另一种讨论。)

一旦您了解了BTree的工作原理(请参阅维基百科),我们就可以讨论InnoDB中叶节点中的内容。

案例1:“数据”BTree包含所有列,并根据PRIMARY KEY进行排序。在MySQL中,PK被定义为“唯一”和“集群”。(其他供应商还有其他选择。)

案例2:“次要”INDEX存储在单独的BTree中。在叶节点中,(1)次级索引中定义的列,加上PK列的副本。要使用辅助索引完成SELECT,它必须首先使用索引BTree获取PK,然后通过数据BTree获取数据。(如果索引是“覆盖”的,则不需要第二步。)

在MySQL中没有"Rownum“。

BTrees实际上是B+Trees,从而提高了范围扫描的效率。

InnoDB将给定表的所有BTrees (一个用于data+PK,一个用于每个辅助索引)放入一些表空间。表空间要么是通用表(ibdata1文件),要么是特定于表的表(文件tablename.ibd),或者是(在新版本中)可以包含多个表的“表空间”文件。

警告:我所描述的内容适用于MySQL的InnoDB,而且可能对任何其他引擎都不正确。

我不知道一个很好的工具来检查InnoDB的BTrees而不深入到血淋淋的细节。关于Percona版本:

代码语言:javascript
运行
复制
SELECT  i.INDEX_NAME as Index_Name,
                IF(ROWS_READ IS NULL, 'Unused',
                    IF(ROWS_READ > 2e9, 'Overflow', ROWS_READ)) as Rows_Read
            FROM (
                SELECT DISTINCT TABLE_SCHEMA, TABLE_NAME, INDEX_NAME
                    FROM information_schema.STATISTICS
                 ) i
            LEFT JOIN information_schema.INDEX_STATISTICS s
                     ON i.TABLE_SCHEMA = s.TABLE_SCHEMA
                    AND i.TABLE_NAME = s.TABLE_NAME
                    AND i.INDEX_NAME = s.INDEX_NAME
            WHERE i.TABLE_SCHEMA = ?
              AND i.TABLE_NAME = ?
            ORDER BY IF(i.INDEX_NAME = 'PRIMARY', 0, 1)

对于MySQL (甲骨文):

代码语言:javascript
运行
复制
SELECT  last_update,
                n_rows,
                'Data & PK' AS 'Type',
                clustered_index_size * 16384 AS Bytes,
                ROUND(clustered_index_size * 16384 / n_rows) AS 'Bytes/row',
                clustered_index_size AS Pages,
                ROUND(n_rows / clustered_index_size) AS 'Rows/page'
        FROM mysql.innodb_table_stats
        WHERE ( ( database_name = ? AND table_name = ? )
          OR    ( database_name = LOWER(?) AND table_name = LOWER(?) 
    UNION
        SELECT  last_update,
                n_rows,
                'Secondary Indexes' AS 'BTrees',
                sum_of_other_index_sizes * 16384 AS Bytes,
                ROUND(sum_of_other_index_sizes * 16384 / n_rows) AS 'Bytes/row',
                sum_of_other_index_sizes AS Pages,
                ROUND(n_rows / sum_of_other_index_sizes) AS 'Rows/page'
        FROM mysql.innodb_table_stats
        WHERE ( ( database_name = ? AND table_name = ? )
          OR    ( database_name = LOWER(?) AND table_name = LOWER(?) 
          AND sum_of_other_index_sizes > 0
票数 4
EN

Stack Overflow用户

发布于 2018-12-19 20:30:55

从MySQL用户的角度来看,这种聚集索引业务是一个实现细节。

表中的信息必须存储在存储设备上,如SSD或硬盘驱动器。很大程度上取决于数据库服务器的版本和特定的访问方法(InnoDB,MyISAM,.)正在使用中。

其中一些信息是元数据:表的描述。MySql通常将其存储在table.frm文件中。行中的信息通常存储在容器文件tablename.ibd中。这些文件只应由MySQL服务器或其他为此目的构建的软件来解释;典型的独立程序无法理解它们--,尤其是如果MySQL服务器处于活动状态,则MySQL。换句话说:如果您编写一个程序来更改任何这些文件,将损坏您的数据库并丢失表的内容。

容器文件中有一些数据结构被MySQL的access-method代码访问。通常,存储具有主键的表就好像它们是索引一样,每一行的所有数据都挂在每个索引条目上。该数据结构是一个聚集索引。

您不一定要查看运行MySQL服务器的机器的文件系统,而只能指向包含索引、聚集索引或其他任何内容的特定文件。使用InnoDB,您可以指示MySQL使用TABLESPACE命令将特定的文件放在文件系统中。但在MySQL 8中,没有办法将索引放在自己的表空间中。

( Oracle和等产品的数据库管理员将表空间移动到不同的磁盘驱动器,以优化和并行访问。在MySQL中,这没什么大不了的,除非您的表开始占用磁盘驱动器空间的很大一部分。)

票数 1
EN

Stack Overflow用户

发布于 2018-12-19 20:22:39

我想知道是否在聚集索引和非聚集索引中生成索引文件?

InnoDB表(默认引擎类型)在MySQL中始终是群集的。这意味着索引存储所有表列;不需要单独的“堆”表。如果您使用旧的MyIsam引擎,那么该表将有一个堆,并在其之上添加任何额外的索引。

另外,我们能否看到表上的索引文件,即它存储了什么?

“主”索引存储表的所有列:键列和非键列。“次要”索引可以更有选择性,只存储列的一个子集;但是主索引包含所有内容。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53858038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档