【问题标题】:All columns of table should be indexed or not mysql database?表的所​​有列都应该被索引还是不是mysql数据库?
【发布时间】:2012-02-14 22:26:27
【问题描述】:

我想制作一张有 4 列的表格。一列是主键,另外三列是对其他表列的引用。我想用它来加入这四个表来做一个搜索过滤器。这些连接需要时间。

我在想我应该索引这些列,因为我读到在连接条件中使用的列上添加索引 [使它们运行得更快]。我的问题是,如果表的所有列都被索引,会有问题吗?或者有没有其他方法可以降低搜索过滤器的时间复杂度。提前致谢。

更多提示: 表1(主搜索)-1000个条目 首要的关键 fk1 fk2 fk3

Table2-800 条目 PK1 ..(8-9 列)

Table3-700 条目 PK2 ..(10-12 列)

Table2-850 条目 PK3 ..(7-8 列)

【问题讨论】:

  • 您的表使用什么引擎?你使用外键吗?
  • @piotrekkr:我正在使用 MyISAM 引擎。并且没有外键。所有其他 3 个表都有数千个数据,并且会逐日增长。
  • 为什么不只索引您当前正在加入的列?所以说t1 JOIN t2 ON t1.id = t2.id 然后确保你在 t1.id 上有一个索引,在 t2.id 上有一个索引。我真的认为不需要为此单独设置一个表。

标签: mysql performance indexing search-engine


【解决方案1】:

创建索引需要额外的磁盘空间,并且索引过多会导致文件系统大小限制产生问题,必须仔细考虑选择正确的索引字段。

由于索引仅用于加快在记录中搜索匹配字段的速度,因此在执行插入或删除操作时,仅用于输出的索引字段只会浪费磁盘空间和处理时间,因此应该避免。同样考虑到二分搜索的性质,数据的基数或唯一性也很重要。对基数为 2 的字段进行索引会将数据分成两半,而基数为 1,000 的字段将返回大约 1,000 条记录。如此低的基数,效率降低为线性排序,如果基数大于记录数的 30%,查询优化器将避免使用索引,有效地使索引浪费空间。

所以最好在列组上添加索引。

【讨论】:

    【解决方案2】:

    要正确索引您的数据以获得性能,您需要了解您的数据。假设我正在创建一个人口普查数据库表:

    CREATE TABLE CENSUS
    (
        ID INTEGER NOT NULL,
        GENDER CHAR(1) NOT NULL,
        FAVOURITEFOOD NVARCHAR(20) NOT NULL,
        STATE NVARCHAR(20) NOT NULL
    );
    

    由于处理数据,我可能知道:

    • 性别分为 50% 男性,50% 女性
    • 60% 喜欢烤肉,20% 吃素,20% 喜欢亚洲食物,20% 喜欢意大利面
    • 加州占 25%,纽约占 25%,其余各占 1%。

    如果我想搜索喜欢烤肉并居住在加利福尼亚的男性,我会考虑制作多列索引,将 STATE 放在首位(STATE、GENDER、FAVOURITEFOOD)。我将 FAVOURITEFOOD 设为索引中的最后一列。这是因为 STATE 过滤器会将数据削减 25%,而 FAVOURITEFOOD 将返回数据库的大部分内容(不比全表扫描好)。

    如果我想搜索喜欢素食并住在纽约的女性,我会考虑制作一个多列索引并将 FAVOURITEFOOD 放在首位(FAVOURITEFOOD, STATE, GENDER)。在这里,FAVOURITEFOOD 将数据削减了 20%,因此与其他两列相比,它是一个更好的选择。

    如果我经常运行这两个查询,我应该创建哪个索引?答案是:

    CREATE INDEX IX_CENSUS_001 ON CENSUS (STATE, GENDER, FAVOURITEFOOD);
    CREATE INDEX IX_CENSUS_002 ON CENSUS (FAVOURITEFOOD, STATE, GENDER);
    ANALYZE TABLE CENSUS;
    

    ANALYZE TABLE 命令存储表的密钥分布。现在,当您运行任一查询时,它将确定 IX_CENSUS_001 还是 IX_CENSUS_002 是执行计划的最佳索引。

    如果我希望开始运行不同类型的查询,我会停下来重新考虑我的数据。我可能需要添加一个新索引,并且可能需要再次运行 ANALYZE TABLE。

    所以,回到你的场景;这取决于您在表中拥有的数据以及您希望对其执行的查询。

    【讨论】:

      【解决方案3】:

      索引不是灵丹妙药。

      当然,它们可以加快查询速度,但也会减慢写入速度(插入/更新/删除)并占用宝贵的 RAM。

      小心使用它们。

      【讨论】:

      • 确实,如果不了解更多关于它们引用的表的大小、基数和表。
      【解决方案4】:

      在引用表列中,必须有一个索引,其中外键列按相同顺序列为第一列。

      如果引用表不存在,则会自动在其上创建此类索引。

      通过以下文章了解击球手:How To Index For Joins With MySQL

      【讨论】:

      • 参考资料提供了很好的解释。尽管它已过时且不再受支持,但它提供了丰富的信息并且很有用。
      【解决方案5】:

      MySQL 允许多种类型的索引,如主键索引、唯一索引、普通索引也称为(“非唯一索引”、普通索引、无约束索引)和全文索引。当然,索引会提高SELECT 查询速度非常快,但是它们也有一些相当大的缺点。 MySQL 索引的优点

      一般来说,将 MySQL 索引到数据库中会给您带来三个优势:

      Query optimization: Indexes make search queries much faster.
      Uniqueness: Indexes like primary key index and unique index help to avoid duplicate row data.
      Text searching: Full-text indexes in MySQL version 3.23.23, users have the opportunity to optimize searching against even large amounts of text located in any field indexed as such.
      

      check out this

      【讨论】:

        【解决方案6】:

        为列添加索引意味着数据库必须在每次写入时做更多工作,但可以节省一些读取时间。

        如果您的查询需要很长时间,为连接添加覆盖索引可以大大加快处理速度,但与所有优化工作一样,请确保您有合适的指标来与“优化”前后进行比较!

        但是,由于您是在每列加入一个表,因此不需要索引,因为您已经拥有主键,并且无论如何都需要读取完整的行。

        【讨论】:

          【解决方案7】:

          我认为索引所有四列并不会真正提高您的性能,因为您仍然需要完整的索引扫描,这基本上与完整的表扫描相同。您的索引将只是表中数据的重复。您可以粘贴您的查询吗?

          【讨论】:

            【解决方案8】:

            如果将主表的主键添加到其他表并在此字段上连接表,而不是添加索引。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-25
              • 2018-05-15
              • 1970-01-01
              • 2011-11-21
              相关资源
              最近更新 更多