选择查询优化

Posted

技术标签:

【中文标题】选择查询优化【英文标题】:Select query optimisation 【发布时间】:2012-06-28 11:25:26 【问题描述】:

我有一个包含 ID、日期和其他列的大表。 ID 是索引和顺序的。

我想选择某个日期之后的所有行。鉴于 ID 是连续的,如果行按 ID 降序排列,则一旦第一行未通过日期测试,则无需进行检查。我怎样才能利用索引来优化呢?

【问题讨论】:

您是否总是在搜索确切的日期而不是时间组件?如果是这样,您可以维护另一个具有每个日期的第一个和最后一个 id 的表,然后只需对该范围进行查找。 @Michael,你能告诉我你现在在没有表现的情况下是怎么做的吗? @Romil 有这样的效果:select id from tablename where date>'some date' @MartinSmith 是的确切日期,但我不认为添加表格是一种选择 【参考方案1】:

你可以这样做:

With FirstFailDate AS
(
-- You start by selecting the first fail date
SELECT TOP 1 * FROM YOUR_TABLE WHERE /* DATE TEST FAILING */ ORDER BY ID DESC
)
SELECT *
FROM YOUR_TABLE t
-- Then, you join your table with the first fail date, and get all the records
-- that are before this date (by ID)
JOIN FirstFailDate f
  ON f.ID > t.ID

【讨论】:

+1 这是答案。但无论如何,日期字段上的索引可能是个好主意。 提前在YOUR_TABLE 上完成扫描所节省的读取次数将与确定TOP 1 时消耗的次数相同,不是吗?【参考方案2】:

如果没有实际索引日期,我认为没有很好的“合法”方式来做到这一点。

但是,您可以尝试以下方法:

向 DBMS 发出以下查询:SELECT * FROM YOUR_TABLE ORDER BY ID DESC。 开始获取客户端应用程序中的行。 在获取时,请检查日期。 当日期超过限制时停止获取(并关闭光标)。

这个想法是 DBMS 有时不必在开始将部分结果发送到客户端之前完成整个查询。在这种情况下,希望 DBMS 将对 ID 执行索引扫描(由于 ORDER BY ID DESC),您将能够在发生时得到结果,然后在之前停止它它甚至已经完成了。

注意:如果您的 DBMS 让您可以选择在快速获取第一行与快速获取整个结果之间取得平衡,请选择第一个选项(例如 Oracle 下的 /*+ FIRST_ROWS */ 提示)。

当然,对真实数量的数据执行测量,以确保这在您的特定情况下确实有效。

【讨论】:

以上是关于选择查询优化的主要内容,如果未能解决你的问题,请参考以下文章

使用嵌套选择优化查询

选择查询需要很长时间执行 - 查询优化

按优化排序复杂选择查询

mysql的子查询中有统计语句 我该如何优化

使用多个选择作为列优化查询

选择查询优化