需要帮助调优sql-query

时间:2010-03-25 10:17:57

标签: sql oracle performance

我需要一些帮助才能提升这个SQL语句。执行时间约为125毫秒 在我的程序运行期间这个sql(更好:不同表格的结构相同的sqls)
将被称为300.000次。

表中的平均行数约为10.000.000行,每天将添加新行(更新/插入)和时间戳。这个特定出口计划的有趣数据在过去的1-3天内。也许这对创建索引很有帮助。我需要的数据是给定id的当前有效行和获取更新的forerunner数据行(如果存在)。

我们使用Oracle 11g数据库和Dot.Net Framework 3.5

要提升的SQL语句:

select 
  ID_SOMETHING,    -- Number(12)
  ID_CONTRIBUTOR,  -- Char(4 Byte)
  DATE_VALID_FROM, -- DATE
  DATE_VALID_TO    -- DATE

from
  TBL_SOMETHING XID

where
  ID_SOMETHING = :ID_SOMETHING
  and ID_CONTRIBUTOR = :ID_CONTRIBUTOR
  and DATE_VALID_FROM <= :EXPORT_DATE
  and DATE_VALID_TO >= :EXPORT_DATE

order by
  DATE_VALID_FROM asc;

我在这里上传了此查询的当前Explain-Plan

我不是数据库专家,因此我不知道哪种索引类型最适合此要求。 我已经看到可以应用许多不同的可能索引类型。 也许Oracle Optimizer Hints也很有帮助。

有没有人有一个好主意来调整这个SQL或者能指出我正确的方向?

3 个答案:

答案 0 :(得分:5)

解释计划看起来尽可能好,但这并不一定意味着什么。 Quassnoi提出的指数正是我的建议。

无论如何,在你的程序中做了300000个类似的查询让我问:这有必要吗?也许你可以用更少的查询达到相同的目标,每个查询都做得更多。

如果你不能避免这么多的查询,你应该至少使用预备语句。如果你使用LINQ,那就是你编译的语句。这样,您就可以避免解析开销,这可能是整体支出的一个相当大的部分,特别是对于这种简单的查询。

答案 1 :(得分:4)

创建综合索引:

CREATE INDEX ix_something_s_c_d ON tbl_something (id_something, id_contributor, date_valid_from)

不幸的是,您正在搜索两列范围内的常量,而不是两个常量范围内的列,因此最后一个字段的选择性不是很高。不过,它可以帮助订购。

答案 2 :(得分:1)

你说:

  

对此感兴趣的数据   特别是出口计划在于   过去1-3天。

这是否意味着您对DATE_VALID_FROM在过去三天内的行感兴趣?如果是这样,您可以从索引中获得更多欢乐:

create index something_idx 
  on tbl_something (date_valid_from, id_something, id_contributor, date_valid_to)
/

包括date_valid_to意味着索引读取可以满足查询而不会触及表。 date_valid_from的前导将所有可能感兴趣的行放在同一块索引空间中。

以上假设您的300,000次调用适用于id_somethingid_contributor的各种不同值。如果这个假设是假的 - 说它们都是相同的id_contributor,或者你连续执行50,000个同一个id_contributor的调用 - 那么用(id_contributor, date_valid_from ...)引导会更有意义。通常情况下,查询调优的业务逻辑细节对于找到满意的结果至关重要。哦,对不同的想法进行基准测试至关重要。

我同意AmmoQ的意见,即在一个过程中执行相同的语句300,000次听起来像一个RBAR实现,可能更适合面向集合的方法。