在关系数据库中,将在查询中排序的所有列都应该有索引吗?

Posted

技术标签:

【中文标题】在关系数据库中,将在查询中排序的所有列都应该有索引吗?【英文标题】:In a relational database, should all columns that will be ordered in a query have an index? 【发布时间】:2017-12-24 15:19:12 【问题描述】:

我正在通过 ORM 访问数据库(主要是 MS SQL Server、Postgre)并通过代码定义属性(例如字段/列是否应该有索引)。

我在想,如果一个列将通过 ORDER BY 排序,它应该有一个索引,否则每次都需要全表扫描(例如,如果你想获得按日期排序的前 5 条记录)。

当我在代码中定义这些索引时(在实体框架 POCO 实体上,作为 .NET 属性),我可以在运行时访问这些元数据。在网格中显示数据时,我打算只对那些具有索引属性的列进行排序(通过单击列标题)。我的想法是否正确,或者可能存在一些合理的条件,可以在非索引列上进行排序,反之亦然(索引列排序没有多大意义?..)

简而言之,假设只有那些列在 UI 中是可排序的,并且在数据库级别应用了相应的索引,这是否很好?

或者,用更一般的问题来表述:将要排序的列是否应该始终具有某种索引?

【问题讨论】:

【参考方案1】:

您是否需要索引取决于您查询有序序列的频率与您进行可能影响有序序列的更改的频率。

每次您进行影响有序序列的更改时,您的数据库都必须重新排序有序索引。因此,如果您进行的更改比查询多得多,那么索引的排序频率将比使用排序结果的频率高。

此外,这取决于谁愿意等待结果:做出需要重新索引的更改的人,或者执行查询的人。

如果索引在更改后由单独的进程排序,我不会感到惊讶。如果在排序未完成的情况下完成查询,则数据库需要先完成足够的排序,然后查询才能返回。

另一方面,如果在由于较早的更改而需要的排序尚未完成时进行了新的更改,则数据库可能不会完成先前的排序,而是开始排序新的情况。

所以我想每个查询都有一个有序索引不是强制性的。对所有可能的列组合进行排序将是一项繁重的工作,但如果等待结果的进程经常请求某种排序,则创建有序索引可能是明智之举。

【讨论】:

【参考方案2】:

order by 不要求对列进行索引,但如果没有索引,那么它最终会进行文件排序而不是索引排序,因此如果您打算使用这些列,则始终首选将它们编入索引WHERE / JOIN ON / HAVING / ORDER BY.

您可以生成查询执行计划并查看版本之间的差异(索引而不是非索引)

【讨论】:

【参考方案3】:

感谢@Harald Coppoolse 提供全面的答案 - 关于在数据库上进行排序,您还应该了解其他一些事情,并且最好在应用程序级别完成。请参阅以下列表中的第 2 项:https://www.brentozar.com/archive/2013/02/7-things-developers-should-know-about-sql-server/

【讨论】:

以上是关于在关系数据库中,将在查询中排序的所有列都应该有索引吗?的主要内容,如果未能解决你的问题,请参考以下文章

mysql索引和查询优化

mysql索引和查询优化

SQL server中的物理排序和逻辑排序是怎么回事

sqlserver 索引

mariadb之查询及存储引擎

sqlServer-索引