【问题标题】:Need help in tuning a sql-query在调整 sql 查询方面需要帮助
【发布时间】:2010-03-25 10:17:57
【问题描述】:

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

表中的平均行数约为 10.000.000 行,并且每天都会添加带有时间戳的新行(更新/插入)。对这个特定的导出程序感兴趣的数据位于最近 1-3 天。也许这对创建索引很有帮助。我需要的数据是给定 id 的当前有效行和获取更新的先行数据行(如果存在)。

我们使用 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 优化器提示也很有帮助。

有没有人有调整这个 sql 的好主意或者可以指出正确的方向?

【问题讨论】:

    标签: sql oracle performance


    【解决方案1】:

    解释计划看起来尽可能好,但这并不一定意味着什么。 Quassnoi 提出的索引也正是我所提出的。

    不管怎样,在你的程序中做 300000 个类似的查询让我问:这有必要吗?也许您可以通过更少的查询达到相同的目标,每个查询都做得更多。

    如果你不能避免做这么多查询,你至少应该使用准备好的语句。如果您使用 LINQ,那是为您编译的语句。这样一来,您就可以避免解析开销,这可能是总开销的很大一部分,尤其是对于此类简单的查询。

    【讨论】:

    • 我已经使用了准备好的语句,不幸的是,由于客户的需求,我需要这个请求总和,我应该能够逐个导出每个项目。 :(但也许我只需要两种不同的出口,这样客户的需求就会得到满足,整体出口也很快。
    【解决方案2】:

    创建复合索引:

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

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

    【讨论】:

    • 我的“测试”表已经有这个索引,但是我检查了我的程序请求的所有表,我发现至少有五个表没有这个特定的索引。我将应用它并检查结果。感谢您的回答。
    【解决方案3】:

    你说:

    对此感兴趣的数据 特定的出口计划在于 过去 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,或者你连续对同一个id_contributor 执行50,000 次调用——那么以(id_contributor, date_valid_from ...) 领导会更有意义。与查询调优的情况一样,业务逻辑的细节对于找到满意的结果至关重要。哦,对不同的想法进行基准测试是必不可少的。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      相关资源
      最近更新 更多