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 INDEX
和DROP 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 是不是使用现有索引来创建新索引?的主要内容,如果未能解决你的问题,请参考以下文章