mysql中的数据库集群索引

luaexgnf  于 2021-06-15  发布在  Mysql
关注(0)|答案(3)|浏览(374)

我正在学习数据库索引。根据Geeksforgeks的说法(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 ,提到
如果一个表有一个聚集索引,它基本上意味着索引就是表
我想知道是否在聚集索引和非聚集索引中生成索引文件?
另外,我们能看到表上的索引文件吗,即它存储了什么?

dojqjjoe

dojqjjoe1#

mysql基本上只有一种索引方法:btree(是的,也有空间和全文,但这是另一个讨论。)
一旦您了解了btree的工作原理(参见wikipedia),我们就可以讨论innodb中的叶节点是什么。
案例1:“data”btree包含所有列,并根据 PRIMARY KEY . 在mysql中,pk的定义是“惟一的”和“集群的”(其他供应商有其他选择。)
案例2:一个“次要的” INDEX 存储在单独的btree中。在叶节点中是(1)在次索引中定义的列,加上pk列的副本。完成 SELECT 使用辅助索引,它必须首先使用索引btree获取pk,然后通过数据btree获取数据(如果索引为“覆盖”,则不需要第二步。)
mysql中没有“rownum”。
btrees实际上是b+树,因此使范围扫描更有效。
innodb将给定表的所有btree(一个用于data+pk,每个二级索引一个)放入某个表空间。表空间不是泛型表空间就是泛型表空间( ibdata1 文件),一个特定于表的文件 tablename.ibd ),或(在较新版本中)可以包含多个表的“表空间”文件。
注意:我所描述的适用于mysql的innodb,可能不适用于任何其他引擎。
我不知道有什么好的工具可以用来检查innodb的btrees而不涉及到血淋淋的细节。对于percona版本:

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(oracle):

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
kgsdhlau

kgsdhlau2#

我想知道是否在聚集索引和非聚集索引中生成索引文件?
mysql中的innodb表(默认引擎类型)总是集群的。这意味着索引存储所有表列;不需要单独的“堆”表。如果您使用旧的myisam引擎,那么该表将有一个堆,再加上任何额外的索引。
另外,我们能看到表上的索引文件吗,即它存储了什么?
“primary”索引存储表中的所有列:键列和非键列“次要”索引可以更具选择性,只存储列的一个子集;但是第一个拥有一切。

rn0zuynd

rn0zuynd3#

从mysql用户的Angular 来看,聚集索引业务是一个实现细节。
表中的信息必须存储在存储设备(如ssd或硬盘驱动器)的某处。很大程度上取决于数据库服务器的版本和使用的特定访问方法(innodb、myisam等)。
有些信息是元数据:表的描述。mysql经常将其存储在 table.frm 文件。行中的信息通常存储在容器文件中 tablename.ibd . 这些文件只能由mysql服务器或其他为此目的而构建的软件进行解释;一个典型的独立程序无法理解它们,特别是当mysql服务器处于活动状态时。换句话说:如果您编写一个程序来更改这些文件中的任何一个,您将损坏数据库并丢失表的内容。
在容器文件中有一些由mysql的访问方法代码访问的数据结构。通常,具有主键的表被存储为索引,每一行的所有数据都挂在每个索引项上。该数据结构是一个聚集索引。
您不必查看运行mysql服务器的机器的文件系统,并指向包含索引、聚集索引或其他内容的特定文件。使用innodb,您可以指示mysql使用表空间命令将数据放入文件系统中的特定文件中。但是在mysql 8中,没有办法将索引放在自己的表空间中。
(oracle和ms sql server enterprise edition等产品的数据库管理员可以将表空间移动到不同的磁盘驱动器,以优化和并行化访问。在mysql中,这并不是什么大事,除非您的表开始占用大量磁盘驱动器空间。)

相关问题