【问题标题】:SQL (Oracle) : how to improve a select ordered by x descSQL (Oracle):如何改进按 x desc 排序的选择
【发布时间】:2012-06-13 21:12:28
【问题描述】:

我在数据库中有一个巨大的日志表。 log_id 和 log_date 上有一个索引。

当我以相反的顺序查询日志时,需要“永远”才能完成。 虽然我在没有顺序的情况下进行相同的查询,但答案是立竿见影的。

如何调整表/改进查询以进行快速(呃)反向选择?

编辑:查询(对不起,查询在我的脑海中很明显(在弗洛林也是如此!):

select * from logs ordered by log_date desc

一些指标:

表中有大约 4000 万行

select * from logs where log_id < 500 

--> 0.032 秒内获取

select * from logs where log_id < 500 order by log_time desc;

--> 大约 20 秒内获取

$max 是最大的 log_id,它已在另一个查询中检索到

select * from logs where log_id > ($max - 500);

--> 大约 16 秒内获取

select * from logs where log_id > ($max - 500) order by log_time desc;

--> 大约 16 秒内获取

我的问题是如何改进所有执行时间过长的查询。

@弗洛林
使用 'where' 子句缩短登录时间(where log_time &gt;= truncate(sysdate)) 我有很好的性能,但我需要能够选择很长一段时间或过去很远的范围内的日志。在这种情况下,查询仍然很慢(比如 20 秒)。

【问题讨论】:

  • 查看 dba.se 上的反向键索引 this answer 以及可能的 IOT 以获取“严重”change the DB 答案。不过可能有更简单的方法。您是否考虑过物化视图?
  • 如果您不提供查询或架构,您希望我们猜测还是通灵?
  • @Ben,反向键索引与在这种情况下的帮助完全相反(RK 索引没有按相反顺序排序,键值本身是字节反转的,这有效地将值分散在指数)。 Oracle 可以在任一方向上遍历普通索引。
  • @Dems,不是通灵者,我希望你聪明;)(我在开玩笑,我觉得自己像个白痴一样没有提供查询)
  • select * from logs where log_id &lt; ($max - 500); 应该是select * from logs where log_id &gt; ($max - 500);

标签: sql performance oracle


【解决方案1】:
select * from log_table 
where log_date >= trunc(sysdate)  --current_day
order by log_id desc, log_date desc

这将在 log_date 索引中进行范围扫描,并将从 log_table 中检索一天的行,而不是整个表。 之后排序会更快,因为要排序的行数很少。

更新: 您可以做的其他事情:

  • 将 log_date 列设为NOT NULL(这可能会将优化器更改为 使用索引);
  • 使用/*+parallel(logs 8)*/ 提示(如果你不射击 这个查询太频繁了,只需要在你的数据库工具中快速得到结果。如果你有很多处理器:) )
  • 您可以按月或更详细的方式对表进行分区。

【讨论】:

  • 谢谢弗洛林,是的,这大大改善了查询。但我需要能够及时执行搜索(过去 10 天,上个月,5 个月前的 20 日和 25 日之间......而在这种情况下,查询仍然真的太慢了​​
  • 我明白了,但是当你想查看整个历史记录是一个特例,当你想分析一些东西的时候。在正常使用日志时,您想查看昨晚或昨天发生的事情。为什么要始终“从 log_date desc 排序的日志中选择 *”?
  • 不,我不想总是选择整个历史记录。我只是惊讶地发现一个简单的逆序查询如此缓慢。但是在表末尾的日期范围内查询很慢(通常在最近几天搜索日志)这一事实非常烦人。有什么方法可以告诉 Oracle 该表将以反向方案访问?
  • 在答案中查看我的另一个提示。 Oracle 做了大量工作来对数据进行排序。
  • 非常感谢。我从未听说过提示。我知道分区,但我以前从未这样做过(你可以猜到管理数据库不是我的主要技能)。我正在阅读范围分区,但它看起来很微妙 (rittmanmead.com/2008/09/…)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 2016-06-07
相关资源
最近更新 更多