【发布时间】:2010-02-17 03:40:27
【问题描述】:
如何确定我的 MySQL 表上是否有太多索引?
对于一些需要大量访问的表,我在将要经常访问的列上添加了大约 2-4 个索引。但是我如何才能知道它们是否弊大于利呢?
【问题讨论】:
标签: php mysql database-design
如何确定我的 MySQL 表上是否有太多索引?
对于一些需要大量访问的表,我在将要经常访问的列上添加了大约 2-4 个索引。但是我如何才能知道它们是否弊大于利呢?
【问题讨论】:
标签: php mysql database-design
请注意,当您使用索引更新表时,唯一的性能损失会出现,因为必须在表中的数据更改时维护所述索引。如果您只是从表中选择,索引通常只能提高性能而不会降低性能。显然,您需要清除表中所有未使用的索引,因为它们会不必要地浪费磁盘空间,并且随着时间的推移,必须再次维护表。
通常,您需要检查您的执行计划,以了解根据您的查询实际使用了哪些索引。确保在执行此操作之前收集统计数据以获得准确的结果。对执行计划进行此检查很重要,b/c 即使您在列上有索引,优化器也可能不会根据列的基数等因素选择它。在查询具有高度选择性的大型表上(即您有 100 万用户,并且您查询的是 userid = 'x' 将返回 1 行的位置),您会发现选择的索引值得维护成本。小表,比如大洲名称表,通常不会从索引中受益很多,因为全表扫描比索引扫描更受欢迎。这是因为读取索引,然后读取索引引用的数据块,而不是直接读取少量数据,成本会更高。同样,这些事情需要根据您的具体表格和需求进行验证,这一切都通过查看执行计划来完成。
如果您的查询适合这些类型的查询,则优先使用串联索引而不是单列索引。例如,如果您的 where 子句通常执行类似“where emp_fname = 'jim' 和 emp_lname = 'smith',请在 fname 和 lname 上创建一个串联索引,而不是在每一列上创建单独的索引。
【讨论】:
这个问题有很多要素:
回答这些问题取决于您对查询的控制。假设您有一个 Web 应用程序,您可能对传入的查询有一个很好的了解。如果没有,请启用查询日志一段时间以查看发生了什么。
接下来,对这些查询中的每一个运行 EXPLAIN 并记下正在使用哪些索引来满足它们。如果有任何未使用,那么您可能应该删除它们以节省空间和 INSERT 损失。
接下来,您需要查看索引是否有帮助。基准测试是最准确的方法,但您可能希望在数据库的副本而不是实时生产副本上执行此操作。
【讨论】:
如果您插入和更新很慢是一种判断方法。
【讨论】:
索引过多的危险在于它们可能会减慢插入/更新/删除的速度,因为需要重新计算索引。插入/更新/删除的基准性能。如果您没有发现索引的性能明显下降,请不要理会它们。
【讨论】:
有两种技术。
获取最常见查询的查询执行计划。检查正在使用的索引。所有其他索引——没有出现在查询执行计划中——都没有被使用。
衡量所选查询的性能。删除索引。再次测量性能,看看它是否变得更糟。
您必须考虑插入和更新活动以及选择活动。索引使选择快,但插入慢。
不要简单地研究或衡量一项交易。决定指数价值的是交易的整体组合。
在某些情况下,您可以考虑删除一些索引以进行插入,然后重新构建它们。
【讨论】: