Den*_*nis 12 sql sql-server indexing performance select
可能重复:
添加索引后查询的性能下降
在阅读了有关SQL Server索引的一些内容以及它们对更新/插入的选择和缺点的性能优势之后,我想知道使用不当的索引是否实际上也会损害选择的性能.如果索引降低纯选择查询的性能,必须满足哪些条件?存在这样的情况吗?
谢谢!
(虽然我总是尝试包含代码示例,但我想不出任何可以支持这个问题的东西......)
LSe*_*rni 13
是的,虽然非常轻微 - 如此轻微,以至于回答"否"也是合理的.
如果您有一个可能被考虑用于查询但不可用的索引,优化器将浪费很短的时间来思考是否以及如何使用它(在极少数情况下使用REALLY复杂的索引和视图,并且在索引性能提示时更频繁)如果错了,您最终可能会选择次优的查询计划.
有些案例是:
在前两种情况下,查询时间是相同的(并且需要完整扫描),但在第二种情况下,您还必须分析并丢弃索引.
索引会伤害你 - 所有索引伤害你的地方 - 在插入,删除和更新中.然后,更新查询未使用但受其影响的任何索引都需要写入索引本身.
所以,你会希望有指标,但是尽可能少的,你可以在不牺牲性能的选择.实际上,您可能决定不使用很少使用的SELECT查询的索引,以避免所有其他UPDATE查询不断更新所需的索引.
编辑:在阅读Heinzi的答案之后,我还想补充一点,大多数数据库服务器都有维护工具来分析表和索引(有时也会查询性能计数器),并正确更新Heinzi所说的提示.因此,定期"维护"数据库以保持优化器提供有关可供选择的索引的最新信息也很重要.
有一个非常漂亮的MySQL分析工具,可以实际建议改进现有的索引(删除未使用的密钥,添加有用的密钥):common_schema.这真的值得一看.
是的,索引会损害 SELECT 的性能。了解数据库引擎如何运行非常重要。数据以“页”的形式存储在磁盘上。索引使访问在表中的一列或多列中具有特定值的特定页成为可能。
如果您正在寻找特定值,这非常有用。
但是,考虑一个需要查看表中每一行的查询。如果您浏览该表,您将按顺序读取页面,并且至关重要的是,只需一次读取即可获得页面上的每一行。读取的次数就是表中的页数。此外,页面缓存可以通过前瞻读取来优化读取,并且不再使用的页面将被简单地覆盖。
使用索引进行相同的读取会一次遍历表中的一条记录,而不是一次遍历一页。这会导致随机读取页面。在最坏的情况下,表中的每条记录都会被读取一次——这可能会对性能造成非常严重的影响。另外,索引本身会占用一些页缓存,减少其他操作的内存。
一般来说,SQL 引擎的优化器组件可以很好地区分这两种情况。关键指标之一是查询的选择性。查询返回多少行(优化器根据页数查看)?如果行数与页数大致相同,优化器将考虑全表扫描而不是索引扫描。
肯定还有其他考虑因素,但一般来说,索引甚至会损害简单的选择查询的性能。一般来说,优化器做得很好,但有时也会出现一些不寻常的情况,即使是最好的优化器也会被欺骗。
是的,但这种情况不太可能发生,并且不会影响您使用索引的决定。
有时,SQL Server 查询分析器会选择不是最佳的执行计划。由于可能的执行计划的数量比乍一看要大得多(简单的n
表连接就已经产生了n!
可能的执行计划),因此 SQL Server必须做出有根据的猜测。猜测的本质是它们有时是错误的。
这种情况很少见,但在过去几年里我已经见过几次这样的情况了。在这种情况下(并且仅在这种情况下),如果没有该索引,就会选择更好的计划。然而,删除索引并不是解决这个问题的正确方法,因为索引的存在通常是有原因的。正确的方法是向该查询添加提示(并且仅向该查询添加提示),以帮助优化器选择正确的计划。
归档时间: |
|
查看次数: |
3849 次 |
最近记录: |