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

MySQL索引-有多少足够?

  •  15
  • fabrik  · 技术社区  · 16 年前

    我正试图微调我的MySQL服务器,以便检查我的设置,分析慢速查询日志,并尽可能简化查询。

    如果索引正确,有时就足够了,有时不行。我在某个地方读到过(如果这是愚蠢的,请纠正我),超过我需要的索引会产生相同的效果,比如如果我没有任何索引。

    有多少索引就足够了?你可以说,这取决于数百个因素,但我很好奇,我该如何清理我的房间 mysql-slow.log 足以减少服务器负载。

    此外,我还看到一些“有趣”的日志条目,如下所示:

    # Query_time: 0  Lock_time: 0  Rows_sent: 22  Rows_examined: 44
    SELECT * FROM `categories` ORDER BY `orderid` ASC;
    

    该表正好包含22行,索引设置为 orderid . 为什么这个查询最终会出现在日志中?如果只包含22行,为什么要检查44行?

    6 回复  |  直到 12 年前
        1
  •  22
  •   RC.    16 年前

    索引的数量和做得太多的行将取决于许多因素。在像“categories”表这样的小表上,您通常不想要或不需要索引,这实际上会影响性能。原因是读取索引需要I/O(即时间),然后检索与匹配行关联的记录需要更多的I/O和时间。如果只查询索引中包含的列,则会出现异常。

    在您的示例中,您正在检索所有的列,并且只有22行,因此只进行表扫描并对这些列进行排序而不使用索引可能会更快。优化器可能/应该这样做并忽略索引。如果是这样的话,那么索引只会占用空间,没有任何好处。如果您的“类别”表经常被访问,您可能需要考虑将其绑定到内存中,这样DB服务器就可以访问它,而不必一直到磁盘。

    进行分析时,请确保生成/更新表和索引统计信息,以便确保计算准确。

        2
  •  13
  •   Powerlord    16 年前

    一般来说,所有主键(您没有选择权)、所有外键以及通常用于获取行的任何其他字段都应该有索引。

    例如,如果我通常按用户名查找用户,我会将其编入索引,即使用户ID是主键。

        3
  •  6
  •   Steven Surowiec    16 年前

    索引的数量完全取决于您运行的查询、正在执行的连接类型(如果有)、表中存储的数据类型以及表的大小(以及许多其他因素)。这真的没有确切的科学依据。在你的武器库中,找出如何优化查询的最好工具是 explain . 使用explain,您可以了解正在关闭的联接类型、可能使用的键以及使用的键(如果有)以及联接中每个表检查了多少行。

    使用此信息,您可以决定如何为表设置键和/或修改查询以提高效率。explain的语法非常简单。

    EXPLAIN SELECT * FROM `categories` ORDER BY `orderid` ASC;
    

    注意,解释 实际运行查询。因此,如果您使用它来调试一个运行需要5分钟的查询,explain仍然会非常快。

    添加索引时确实需要小心,因为它们确实会导致插入和更新速度变慢,而且在非常大的表上,这种性能影响可能会变得明显。尤其是当同一个表用于大量读取时。虽然添加大量索引通常不会降低查询的性能,但您仍然应该将它们作为索引添加

        4
  •  5
  •   scotts    15 年前

    每个选择一个索引 语句(尽管如果使用联接,也可以对每个联接使用一个)。所以索引 只是因为 是对磁盘空间的浪费,会降低数据库的写入速度。如果您通常在两列上使用where语句,则执行一个包含这两列的索引,这将比仅对一列进行索引要快得多。

        5
  •  4
  •   Vilx-    16 年前

    索引可以加速SELECT查询,但会减慢INSERT/UPDATE/DELETE查询的速度,因为它们还需要更新索引,而不仅仅是行。

    这只是个人观点(我没有事实支持),但我认为如果有一个查询需要很长时间,并且索引会加快它的速度,那就去做吧!如果您添加的索引没有任何好处(例如,没有查询会加快速度),则会出现“太多”索引。例如,一个愚蠢的做法是在每一列上都放置一个索引“仅仅因为”。

        6
  •  3
  •   Beska    16 年前

    “最佳”索引数没有神奇的数字。基本规则是:为经常使用和/或需要快速运行的查询添加索引。

    拥有“太多”索引不应该会减慢查询速度,但如果每个添加的索引都添加了一小段时间来添加/更新数据库中的项(因为它也会修改索引),并且会增加一小段空间。然而,如果只是根据需要添加索引,这可能不是一个大问题。