MySQL 是不是使用现有索引来创建新索引?

Posted

技术标签:

【中文标题】MySQL 是不是使用现有索引来创建新索引?【英文标题】:Does MySQL use existing indexes on creating new indexes?MySQL 是否使用现有索引来创建新索引? 【发布时间】:2010-10-02 09:52:41 【问题描述】:

我有一个包含数百万条记录的大表。

Table `price`
------------
id 
product 
site 
value

表是全新的,没有创建索引。

然后我使用以下查询发出了创建新索引的请求:

CREATE INDEX ix_price_site_product_value_id ON price (site, product, value, id);

这花了很长时间,上次我检查跑了5000多秒,因为机器。

我想知道如果我发出另一个索引创建,它会在过程计算中使用现有索引吗?如果有,是什么形式?

接下来运行查询 1:

CREATE INDEX ix_price_product_value_id ON price (product, value, id);

接下来运行查询 2:

CREATE INDEX ix_price_value_id ON price (value, id);

【问题讨论】:

【参考方案1】:

我想知道如果我发出另一个索引创建,它会在过程计算中使用现有索引吗?如果有,是什么形式?

不,不会的。

理论上,(site, product, value, id) 上的索引具有在这些字段的任何子集上构建索引所需的一切(包括(product, value, id)(value, id) 上的索引)。

但是,不支持从二级索引构建索引。

首先,mysql 不支持快速全索引扫描(即按物理顺序而不是逻辑顺序扫描索引),从而使索引访问路径比表读取更昂贵。这对InnoDB 来说不是问题,因为表本身总是聚集在一起的。

其次,这些索引中的记录顺序完全不同,所以无论如何都需要对记录进行排序。

然而,MySQL 中索引创建速度的主要问题是它在现场生成订单(只是将记录一一插入到B-Tree)而不是使用预排序的源。正如@Daniel 提到的,快速索引创建解决了这个问题。它可作为5.1 的插件使用,并预安装在5.5 中。

【讨论】:

我肯定会阅读更多关于选择所有东西引擎等的内容,以及索引创建速度如何在不同数据类型上起作用。也许这应该是您博客上新帖子的新材料。你说什么?【参考方案2】:

如果您使用 MySQL 5.1 版和 InnoDB 存储引擎,您可能希望使用 InnoDB Plugin 1.0,它支持名为 Fast Index Creation 的新功能。这允许存储引擎创建索引而无需复制整个表的内容。

InnoDB 插件概述:

从 5.1 版开始,MySQL AB 提出了“可插拔”存储引擎架构的理念,允许向 MySQL 添加多个存储引擎。然而,目前大多数用户只能访问那些由 MySQL AB 分发并链接到二进制(可执行)版本的存储引擎。

自 2001 年以来,MySQL AB 已经分发了 InnoDB 事务存储引擎及其版本(源代码和二进制)。从 MySQL 5.1 版开始,用户可以更换一个版本的 InnoDB 并使用另一个版本。

来源:Introduction to the InnoDB Plugin

快速索引创建概述:

在最高 5.0 的 MySQL 版本中,如果表有很多行,则在包含现有数据的表上添加或删除索引可能会非常慢。 CREATE INDEXDROP INDEX 命令通过创建一个用请求的索引集定义的新空表来工作。然后,它将现有行一一复制到新表中,同时更新索引。以这种方式将条目插入索引中,其中键值未排序,需要随机访问索引节点,并且远非最佳。复制原始表中的所有行后,删除旧表并使用原始表的名称重命名副本。

从 5.1 版开始,MySQL 允许存储引擎创建或删除索引,而无需复制整个表的内容。然而,MySQL 5.1 版中的标准内置 InnoDB 并没有利用此功能。但是,使用 InnoDB 插件,在大多数情况下,用户可以比以前的版本更有效地添加和删除索引。

...

更改聚集索引需要复制数据,即使使用 InnoDB 插件也是如此。但是,使用 InnoDB 插件添加或删除二级索引要快得多,因为它不涉及复制数据。

来源:Overview of Fast Index Creation

【讨论】:

听起来很酷。如何检查机器是否安装了 InnoDB Plugin? 在您的 MySQL 客户端中执行 SELECT VERSION()。你的 MySQL 服务器是 v5.1+ 吗? @Pentium10:很好。那么你可能想按照这里的说明进行操作:Obtaining and Installing the InnoDB Plugin @Pentium10:也可以通过SHOW PLUGINS;命令查看是否已经安装。在此处查看第 6 点中的预期输出:dev.mysql.com/doc/innodb-plugin/1.0/en/… 我已经升级到内置插件的 5.5,现在一切正常。谢谢。

以上是关于MySQL 是不是使用现有索引来创建新索引?的主要内容,如果未能解决你的问题,请参考以下文章

MySql 创建索引原则

wordpress 是不是通过自动索引来优化其数据库表?

在 SQL Server 2017 上创建具有 800+ 百万行的现有分区表的列存储索引

MySQL 索引压缩碎片

应该为此 MySQL 查询创建哪些索引 [关闭]

mysql-冗余和重复索引