如何在海量数据上创建索引(mysql)

时间:2011-10-07 16:46:59

标签: mysql indexing query-optimization scalability

我目前正在评估存储供应商目录的策略。 目录中可以有多个项目从100到0.25百万不等。 每个项目可能有多个错误。应用程序应支持浏览目录项

  • 按错误类型,类别,制造商,供应商等分组。
  • 浏览任何组的项目,应该能够对多个列进行排序和搜索(partid, 名称,价格等。)

问题是当我必须提供“多个搜索和分类和组”的功能时,我应该如何创建索引。

根据mysql doc&对于索引的博客,似乎所有查询都不会使用在单个列上创建索引。

创建多列索引甚至不是我的具体情况。

可能有20 - 30组搜索和组合排序

如何缩放以及如何快速搜索。

期望处理5000万条数据记录。

目前正在评估1500万个数据。

欢迎提出建议。

CREATE TABLE CATALOG_ITEM
(
    AUTO_ID BIGINT PRIMARY KEY AUTO_INCREMENT,
    TENANT_ID VARCHAR(40) NOT NULL,
    CATALOG_ID VARCHAR(40) NOT NULL,
    CATALOG_VERSION INT NOT NULL,
    ITEM_ID VARCHAR(40) NOT NULL,
    VERSION INT NOT NULL,
    NAME VARCHAR(250) NOT NULL,
    DESCRIPTION VARCHAR(2000) NOT NULL,
    CURRENCY VARCHAR(5) NOT NULL,
    PRICE DOUBLE NOT NULL,
    UOM VARCHAR(10) NOT NULL,
    LEAD_TIME INT DEFAULT 0,
    SUPPLIER_ID VARCHAR(40) NOT NULL,
    SUPPLIER_NAME VARCHAR(100) NOT NULL,
    SUPPLIER_PART_ID VARCHAR(40) NOT NULL,
    MANUFACTURER_PART_ID VARCHAR(40),
    MANUFACTURER_NAME VARCHAR(100),
    CATEGORY_CODE VARCHAR(40) NOT NULL,
    CATEGORY_NAME VARCHAR(100) NOT NULL,
    SOURCE_TYPE INT DEFAULT 0,
    ACTIVE BOOLEAN,
    SUPPLIER_PRODUCT_URL VARCHAR(250),
    MANUFACTURER_PRODUCT_URL VARCHAR(250),
    IMAGE_URL VARCHAR(250),
    THUMBNAIL_URL VARCHAR(250),
    UNIQUE(TENANT_ID,ITEM_ID,VERSION),
    UNIQUE(TENANT_ID,CATALOG_ID,ITEM_ID)
);

CREATE TABLE CATALOG_ITEM_ERROR
(
    ITEM_REF BIGINT,
    FIELD VARCHAR(40) NOT NULL,
    ERROR_TYPE INT NOT NULL,
    ERROR_VALUE VARCHAR(2000)
);

1 个答案:

答案 0 :(得分:0)

如果您决定仅在MySQL中执行此操作,那么您应该创建适用于所有查询的索引。如果有20-30个不同的查询进行排序,则可以有20或30个索引。但你可以用更少的索引来做到这一点。

您还需要规划如何维护这些索引。我假设,因为这是供应商目录,数据不会有太大变化。在这种情况下,只需创建所需的所有索引就可以很好地完成工作。如果要实时编辑或插入数据行,那么你必须考虑使用索引 - 那么有20或30个索引可能不是一个好主意(因为MySQL将不断更新它们) 。您还必须考虑使用哪个MySQL存储引擎。如果您的数据永远不会改变,MyISAM(默认引擎,基本上是快速平面文件)是一个不错的选择。如果它发生了很大变化,那么你应该使用InnoDB,这样你就可以获得行级锁定。 InnoDB还允许您定义聚簇索引,这是一个特殊的索引,用于控制存储在磁盘上的订单。因此,如果您有99%的时间运行一个特定查询,则可以为其创建聚簇索引,并且所有数据在磁盘上的顺序已经正确,并且将以超级超快的速度返回。但是,每次插入或更新数据都会导致整个表在磁盘上重新排序,这对于大量数据来说并不快。如果数据经常更改,您永远不会使用一个,并且您可能必须批量加载数据更新(例如供应商百万行的新版本)。同样,它归结为你是否会永远,偶尔或不断地实时更新它。

最后,你应该考虑替代方法而不是在MySQL中这样做。现在有很多非常好的搜索产品,比如Apache Solr或Sphinx(在上面的评论中提到),这可以让你在编写搜索界面时更轻松。您可以在其中一个中索引目录,然后使用它们提供一些非常棒的搜索功能,如全文和/或分面搜索。这就像拥有私人谷歌搜索引擎索引你的东西,是描述这些工作方式的好方法。将代码写入与搜索服务器的接口需要花费时间,但是您很可能会节省时间而不必编写并围绕索引问题以及我上面提到的其他问题。

如果您只是创建所有索引,请学习如何在MySQL中使用EXPLAIN命令。这将让您了解MySQL执行查询的计划是什么。您可以创建索引然后在查询上重新运行EXPLAIN,并查看MySQL将如何使用它们。这样,您可以确保每个查询方法都有支持它的索引,并且不会回退到扫描整个数据表来查找内容。正如您所说的那样,每个查询必须能够使用索引来查找其数据。如果你做对了,它会表现得很好。