使用where子句中的列优化查询

时间:2012-06-10 14:27:33

标签: sql database database-agnostic

我有一个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。
  • 当行在队列中时,
  • status为0。稍后它会更改为1以表示它正在处理中。处理后,它将被删除。因此,预计表中至少90%的行将处于状态0。
  • 表中的行应根据其日期获取,因此order by子句。

使此查询最快的最佳索引是什么?

我最初认为索引应该在(date, status)上,但我不再确定了。由于状态列将主要包含零,是否有附加值?单独按(date)索引是否足够? 或者它应该是(status, date)

2 个答案:

答案 0 :(得分:2)

我认为没有一种有效的解决方案可以独立于RDMS。例如,Oracle有位图索引,SQLServer有部分索引,我没有看到不使用它们的原因,例如,Mysql或Sqlite没有类似的东西。此外,历史上SQLServer实现集群表(或Oracle世界中的IOT)比Oracle更好,因此在日期列上使用聚簇索引可能对SQLServer完全有效,但对Oracle无效。

我宁愿改变方法。如果你说90%的行不满足status=0条件,为什么不尝试重构模式,并添加一个只保存你感兴趣的记录的新表(或物化视图)?即使RDMS不直接支持物化视图,使该表保持最新并将数据与原始表合并所需的新可编程对象的数量也相对较小。此外,如果可以重新设计底层逻辑,那么行永远不会更新,只插入或删除,那么它将有助于避免锁定争用,因此整个系统将具有更好的性能。

答案 1 :(得分:0)

在Date上有一个聚簇索引,在Status上有一个非聚集索引。