我有一个 SQL 查询,它获取表中的前 N 行,该表被设计为低级队列。
select top N * from my_table where status = 0 order by date asc
此查询背后的意图如下:
- 首先,这个问题与数据库无关,因为我的实现将支持 sql server、oracle、DB2 和 sybase。上面的“top N”的sql语法只是一个示例。
- 该表可以包含数百万行。
- 相比之下,N 是一个相对较小的数字,例如100.
- 当该行在队列中时,状态为 0。后来改为1,表示正在处理中。处理完后就删除了。因此预计表中至少 90% 的行的状态为 0。
- 表中的行应根据日期获取,因此需要
order by
子句。
使该查询运行速度最快的最佳索引是什么?
我最初认为索引应该位于(日期,状态)
,但我不再确定了。由于状态列大部分包含零,因此它有附加值吗?单独按(日期)
建立索引就足够了吗?
或者也许应该是(状态,日期)
?
最佳答案
我认为不存在独立于 RDMS 的有效解决方案。例如,Oracle 有位图索引,SQLServer 有部分索引,如果 Mysql 或 Sqlite 没有类似的索引,我认为没有理由不使用它们。此外,历史上 SQLServer 实现聚簇表(或 Oracle 世界中的 IOT)的方式比 Oracle 更好,因此在日期列上设置聚簇索引可能非常适合 SQLServer,但不适用于 Oracle。
我宁愿稍微改变一下方法。如果您说 90% 的行不满足 status=0
条件,为什么不尝试重构架构,并添加一个仅保存您感兴趣的记录的新表(或物化 View )?即使 RDMS 不直接支持物化 View ,保持该表最新并将数据与原始表合并所需的新可编程对象的数量也相对较少。另外,如果可以重新设计底层逻辑,使行永远不会更新,只插入或删除,那么将有助于避免锁争用,从而整个系统将具有更好的性能。
关于sql - 使用 where 子句中的列优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10969490/