今天,我的一位同事建议我们仔细检查应用程序中的所有查询并相应地添加索引。
我觉得这是过早的优化,因为我们的应用程序尚未发布。我建议我们上线后监视慢速查询,然后相应地添加索引。
在设计数据库时,一般的共识是什么?每次编写新查询时都应添加匹配的索引吗?还是只监视并查看进展情况更好?
今天,我的一位同事建议我们仔细检查应用程序中的所有查询并相应地添加索引。
我觉得这是过早的优化,因为我们的应用程序尚未发布。我建议我们上线后监视慢速查询,然后相应地添加索引。
在设计数据库时,一般的共识是什么?每次编写新查询时都应添加匹配的索引吗?还是只监视并查看进展情况更好?
Answers:
由于模糊,直观的感觉,过早的优化正在“优化”某些东西,您可能知道,这可能会很慢,特别是对代码的可读性和可维护性不利。这并不意味着会故意不遵循公认的良好绩效规范。
有时候这很难画一条线,但是我肯定会说,在上线之前不添加任何索引是太迟的优化;这将惩罚早期采用者-您最渴望和最重要的用户-并给他们负面评价您的产品,然后他们会在评论,讨论等中广泛传播。监视查询以查找需要索引的痛点是好主意,但我会确保不迟于Beta测试。
我们上线后监视慢速查询
因为没有什么能像让您的用户因缺乏设计而遭受苦难的质量了!
设计表时,应该知道哪些查询需要索引,知道在where子句和联接中要查询哪些列。这些应该已经被索引了,因为当负载或存储的数据增加时,在实时环境中可能看不见的内容很快就会变得显而易见。当发生这种情况时,您不想做的就是在每个“慢速”查询上打入索引,最终将得到所有内容的索引。
从贬义上讲,“过早的优化”意味着可能不需要的昂贵的优化。这并不意味着在防止破产前的所有可能的优化措施已实施!
特别是,在上线之前根据性能测试进行优化是合法的,以确保您可以满足一些合理的(尽管是近似的)要求,以使应用程序不会完全崩溃。
至少,您应该使用合理数量的测试数据加载数据库,并检查应用程序的响应能力。这还为时过早,因为您知道它会发生,并且它将捕获任何触发异常缓慢的扫描的查询。正如AE在评论中所说:
使用索引可以避免对最终用户通常实时进行的任何查询进行全表扫描
至少对于计划使用的表。
然后,作为捷径,如果您对数据库引擎有丰富的经验,并且在编写代码的第一部分时已经计划了测试,那么通常甚至在不运行它的情况下,您都知道查询是没有索引,写作将太慢。当然,您可以随意假装不知道,并且可以在添加索引使其通过之前观看测试失败,但是没有理由使已知的错误代码(因为没有响应)上线。
我觉得这是过早的优化,因为我们的应用程序尚未发布。我建议我们上线后监视慢速查询,然后相应地添加索引。
您不能像质量保证那样对待最终用户和生产环境。换句话说,您要在生产中解决这个问题。我认为这不是正确的方法,而且我每天都看到这种方法非常错误。
您需要牢记一件事,因为您不能使用宽泛的画笔来绘制它。
这听起来可能很明显或很乏味,但实际上却很重要。如果您有10个查询构成了您工作量的98%(非常普遍,信不信由你),我的建议是在生产之前进行艰难的分析。使用现实且具有代表性的数据,请确保这10个查询尽可能地完好(完美查询是在浪费宝贵的时间,并且几乎是无法实现的)。
对于其他200个查询(占工作量的2%),这些查询很可能不值得花很多精力,并且将弥补生产中故障排除的特殊情况。这也是现实,不是一件坏事。但这并不意味着忽略索引最佳实践或对数据检索进行估计的假设。
在生产之前确定数据库性能是一种常见且好的做法。实际上,这种类型的东西在开发DBA中有一个相对普遍的立场。
有些人走得太远,疯狂地添加索引以防万一。有人建议这是缺少的索引吗?添加它,以及其他四个变体。也是个坏主意。您不仅需要考虑数据检索,还需要考虑数据修改吗?表上的索引越多,通常来说,修改数据时开销就越大。
像大多数事物一样,保持着健康的平衡。
作为一个有趣的小注意事项...“索引”的复数
“指数”适用于金融界人士
“索引”适合我们
不,这不是过早的优化,但必须正确执行,因为任何优化都应该如此。
这是我会做的:
数据库服务器是复杂而智能的软件。如果您会听,他们会告诉您如何优化他们。
关键是在优化前后评估性能,并让数据库告诉您它需要什么。
遵循已知问题的经过验证的模式(例如通过其ID查找记录)并不为时过早。这是明智的。
也就是说,索引并不总是一件容易的事。在设计阶段通常很难知道您的流量将依赖哪个索引以及哪些瓶颈将成为写操作。因此,我主张利用一些“显而易见的”模式设计最佳实践(使用适合于设计的读/写模式和索引FK的PK);但是,除非压力测试要求,否则不要在其他任何索引上添加索引。
发布应用程序时,为时已晚。
但是任何适当的开发过程都应包括性能测试。
使用性能测试的结果来确定要添加的索引,并通过重复性能测试来验证其有效性。
尽管我不认为每个查询都应该进行优化,但是索引在RDBMS中占据了很大一部分,因此在发布之前需要对其进行考虑。当您执行查询时,与其他形式的编程不同,您不会告诉系统如何执行查询。他们制定自己的计划,并且几乎总是基于索引的可用性。以后还会考虑数据的构成和数量。
这是我要考虑的一些事项:
初次审核后,您应该考虑一些注意事项,以决定何时应再次审核以及如何收集信息以进行此操作(监视使用情况,获取客户端数据的副本等)。
我知道您不想过早地进行优化,但是几乎可以肯定,如果不对数据库建立索引,则性能会很差。通过解决这个问题,您可以确定是否还有其他区域导致性能问题。
通过一些预先的分析来确定哪些列确实需要索引是一个好习惯。如果您绝对没有索引,那么随着数据库大小的增加,生产中确实存在逐渐或意外的性能下降的风险。您要避免的情况是,通常运行的查询需要扫描大量表行。将索引添加到关键列并不是过早的优化,因为您拥有许多可用的必要信息,并且潜在的性能差异非常大(数量级)。在某些情况下,索引的好处不太明确或更多地取决于数据-您可能可以推迟对其中某些情况的决定。
您需要问的一些问题是:
如果表总是很小(例如<100行),那么数据库必须扫描整个表就不会造成灾难。添加索引可能是有益的,但这需要更多的专业知识或度量来确定。
如果查询不经常运行并且没有严格的响应时间要求(例如,报告生成)并且行数不是很大,则推迟添加索引可能是相当安全的。同样,专业知识或度量可以帮助判断它是否将是有益的。
如果这些查询经常运行并且触摸具有很多行的表,那么您应该认真考虑先占添加索引。如果不确定查询是否是这种情况,则可以用实际的数据量填充数据库,然后查看查询计划。