代码之家  ›  专栏  ›  技术社区  ›  Pentium10

MySQL在创建新索引时是否使用现有索引?

  •  2
  • Pentium10  · 技术社区  · 14 年前

    我有一张有数百万张唱片的大桌子。

    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);
    
    2 回复  |  直到 14 年前
        1
  •  4
  •   Community CDub    4 年前

    InnoDB Plugin 1.0 ,它支持一个名为 Fast Index Creation . 这允许存储引擎在不复制整个表的内容的情况下创建索引。

    InnoDB插件概述:

    从5.1版开始,MySQL AB推广了可插拔存储引擎体系结构的思想,它允许向MySQL添加多个存储引擎。然而,目前大多数用户只访问MySQL AB分发的、链接到二进制(可执行)版本的存储引擎。

    自2001年以来,MySQL AB发布了InnoDB事务存储引擎及其版本(源代码和二进制文件)。从MySQL5.1开始,用户可以交换InnoDB的一个版本,使用另一个版本。

    资料来源: Introduction to the InnoDB Plugin

    快速索引创建概述:

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

    ...

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

    资料来源: Overview of Fast Index Creation

        2
  •  5
  •   Quassnoi    14 年前

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

    不,不会的。

    从理论上讲,一个索引 (site, product, value, id) (product, value, id) (value, id) ).

    但是,不支持从辅助索引生成索引。

    第一, MySQL 不支持快速完全索引扫描(即按物理顺序而不是逻辑顺序扫描索引),因此索引访问路径比表读取更昂贵。这对我来说不是问题 InnoDB ,因为表本身总是集群的。

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