MySQL - 为啥不索引每个字段?
Posted
技术标签:
【中文标题】MySQL - 为啥不索引每个字段?【英文标题】:MySQL - why not index every field?MySQL - 为什么不索引每个字段? 【发布时间】:2011-07-23 16:47:20 【问题描述】:最近我了解了索引的神奇之处,并且性能有了显着提高。但是,根据我所学到的一切,我似乎无法找到这个问题的答案。
索引很棒,但为什么不能只索引所有字段以使表格变得异常快呢?我确信不这样做是有充分理由的,但是在一个有 30 个字段的表中三个字段怎么样? 10 在 30 领域?应该在哪里划线,为什么?
【问题讨论】:
尝试将一个值插入到具有超过 10k 个索引条目的表中,由于插入/删除,所有条目都必须更新,如果每个值,这是一个巨大的时间开销和一些内存开销有一个索引 除了空间和写入性能之外还有一个原因:使用multiple indexes for a single table access is very inefficient。这意味着,即使每一列都有一个索引,如果在 WHERE 子句中访问多个列,则选择性能也不是很好。在这种情况下,最好使用多列索引。 如果您有一个包含 30 个字段的表,您应该真正查看您的表结构。他们应该很难相处。 【参考方案1】:索引占用内存 (RAM) 空间;索引太多或太大,数据库将不得不将它们交换到磁盘和从磁盘交换。它们还增加了插入和删除时间(必须为插入/删除/更新的每条数据更新每个索引)。
你没有无限的记忆。使所有索引都适合 RAM = 好。
你没有无限的时间。仅索引您需要索引的列可以最大限度地减少插入/删除/更新性能损失。
【讨论】:
不错的随意回答可以给出一般的理解,但在实际确定在索引上划线的位置方面没有多大帮助。你怎么知道?只需将它们添加到常见的 WHERED 字段并希望获得最好的结果? @Andrew 一年半后,你找到问题的答案了吗? @Sinjai 将它们添加到常用的 where'd 列中可能是一个很好的经验法则。但是,如果你想成为指数专家,你可以做很多阅读。例如。 ***.com/questions/3049283/… 不要忘记磁盘空间。【参考方案2】:请记住,每次更新、插入或删除行时,都必须更新每个索引。因此,您拥有的索引越多,写入操作的性能就越慢。
此外,每个索引都会占用更多的磁盘空间和内存空间(调用时),因此它也可能会减慢读取操作(对于大型表)。 Check this out
【讨论】:
该链接适用于 MS SQL Server;这个问题是针对 mysql @OMG 链接中的大部分内容适用于所有主要的 RDBMS @Richard aka cyberkiwi:ANSI 不涵盖索引 - 每个供应商都使用了类似的术语,这是一个奇迹。但即便如此,也只有 SQL Server 和 MySQL 使用术语“聚集”和“非聚集”索引——这在 SQL Server 中比在 MySQL 中意味着更多。没有什么可以保证对一个供应商的建议应该适用于另一个供应商。 @omg 前 6 点适用于任何 dbms。跳过非/集群的,然后下面是关于一般索引的更多点,也很重要。如果您有具体的事情要指出,请打电话给他们。否则,看起来您正在否定来自 cmets 的所有答案(包括您已删除的答案),没有人同意您的评估。【参考方案3】:您必须平衡 CRUD 需求。写入表变得很慢。至于在哪里划线,这取决于数据的访问方式(排序过滤等)。
【讨论】:
而且每个索引都占用一些数据库空间 @Acanthus:可用的最小硬盘以 千兆字节为单位。 @OMG 但不是 RAM,正如 Brian 指出的那样。 从不存储超过你需要的东西是一个好主意。 RAM 中的数据/索引缓存、备份媒体(适合每个磁带的版本等)都受到无用索引的影响 资源的丰富不是浪费或效率低下的理由。 是的,但约束条件已经不像 10 多年前那样了。【参考方案4】:索引会从驱动器和内存中占用更多分配的空间,但也会大大提高性能。不幸的是,当它达到内存限制时,系统将放弃驱动器空间并危及性能。实际上,您不应该索引任何您可能认为不涉及任何类型的数据遍历算法的字段,既不插入也不搜索(WHERE 子句)。但如果不是这样,你应该这样做。默认情况下,您必须索引所有字段。您应该考虑取消索引的字段是查询是否仅由版主使用,除非他们也需要速度
【讨论】:
【参考方案5】:这个答案是我个人的意见,我用我的数学逻辑来回答
第二个问题是关于边界在哪里停止,首先让我们做一些数学计算,假设我们有 N 行 L 字段如果我们索引所有字段,我们将得到一个新的索引表,每个表都会以一种有意义的方式对索引字段的数据进行排序,乍一看,如果您的表是 W 权重,如果您有 100 个大表,它将变为 W*2(1 tera 将变为 2 tera)(我已经在项目中工作过表数大约是 1800 表)你将浪费这个空间的 100 倍(100 tera),这远非明智之举。
如果我们将在所有表中应用索引,我们将不得不考虑索引更新是一个更新触发器所有索引更新这是一个选择所有无序的等价时间
据此我得出的结论是,在这种情况下,如果您这次松动,最好在选择或更新中丢失它,因为如果您选择一个未编入索引的字段,您将不会触发另一个选择未编入索引的字段
索引什么?
外键:is a must based on
主键:我还不确定如果有人读到这可能对这个案子有帮助
其他字段:第一个自然答案是其余字段的一半为什么:如果您应该索引更多,那么您离最佳答案不远 如果您应该索引更少,那么您也不会太远,因为我们知道没有索引是不好的并且所有索引也很糟糕。
从这 3 点我可以得出结论,如果我们有 L 个由 K 个键组成的字段,则限制应该在接近 ((L-K)/2)+K
或多或少 L/10 的地方
这个答案是基于我的逻辑和个人价格
【讨论】:
【参考方案6】:索引表中的所有列不是一个好主意。虽然这将使表的读取速度非常快,但写入速度也会变得慢得多。写入每个列都被索引的表将涉及将新记录放入该表中,然后将每列的信息放入其自己的索引表中。
【讨论】:
我不确定它是否会让读取表格变得快如闪电,尤其是当数据表只有 100MB 但 index.table 有 300MB 或更多时。 你所说的一切都已经说过了。以上是关于MySQL - 为啥不索引每个字段?的主要内容,如果未能解决你的问题,请参考以下文章