【问题标题】:How to correctly handle dates in queries constraints如何正确处理查询约束中的日期
【发布时间】:2011-02-02 16:05:56
【问题描述】:

我目前正在使用以下查询在 2010 年 6 月完成所有检查:

select inspections.name
from inspections
where
  to_char(inspections.insp_date, 'YYYY') = 2010 and
  to_char(inspections.insp_date, 'MM') = 06;

但这感觉有点尴尬。难道没有更好的方法来做到这一点吗?看着http://infolab.stanford.edu/~ullman/fcdb/oracle/or-time.html 似乎并非如此。我正在使用 Oracle,如果它有所作为的话。

谢谢

【问题讨论】:

    标签: sql database oracle constraints


    【解决方案1】:

    我喜欢尽可能使用范围比较,因为这可以被优化器用于索引扫描:

    select inspections.name
      from inspections
     where inspections.date >= DATE '2010-06-01'
       and inspections.date < DATE '2010-07-01'
    

    【讨论】:

    • hmmmm,反过来,我认为它比原始查询不太清楚:(
    • @devoured elysium :我猜这是主观的,而使用索引的能力不是:)
    • 我认为更清楚的是,当有一个非常好的方法会使用索引时,原始的 qery 和编写的 SQL 永远不会使用索引,这是一个糟糕的主意。任何编写 SQL 的人都需要了解什么是 sargable,什么不是。清晰度(这是程序员的主观判断)不会胜过数据库查询的性能。
    【解决方案2】:

    我同意文森特的回答,但为了完整起见,您可以简化为:

    select inspections.name
    from inspections
    where
      to_char(inspections.insp_date, 'YYYYMM') = '201006';
    

    这甚至可以使用索引,只要索引是:

    create index x on inspections (to_char(insp_date, 'YYYYMM'));
    

    【讨论】:

    • 很难理解 201006 发生了什么 :(
    • @devoured:真的吗?好吧,您可以改用“YYYY-MM”和“2010-06”。
    • 杰弗里你没有认真对待这个!
    【解决方案3】:
    select inspections.name
    from inspections
    where
      extract(year from inspections.insp_date) = 2010 and
      extract(month from inspections.insp_date) = 6;
    

    【讨论】:

    • 看起来不错。但它似乎是某种子查询。有效率吗?谢谢!
    • 没有子查询,只有用于简单函数的 oracle 特定语法。
    • EXTRACT() 并不特定于 Oracle;这是标准 SQL。
    【解决方案4】:

    另一种选择是

    SELECT inspections.name
      FROM inspections
     WHERE TRUNC( inspections.insp_date, 'MM' ) = date '2010-06-01';
    

    从效率的角度来看

    • Vincent 的解决方案可能会在 INSP_DATE 对索引使用范围扫描(假设该表有许多个月的数据,因此索引访问将是最有效的计划)。
    • 假设表有很多个月的数据,我的查询可能会再次在 TRUNC(insp_date, 'MM') 上使用基于函数的索引。如果不同月份的行数有很大差异,则优化器的基数估计在这个基于函数的索引上可能比在直接 INSP_DATE 索引上更准确,但这在查询中不太重要这个简单。但是,如果您开始将此查询嵌套在其他地方,它可能会发挥作用。但是,如果您出于其他原因需要索引 INSP_DATE,则维护两个不同的索引可能会浪费时间和空间。
    • 您的初始查询和 Lev 的查询都可能使用基于复合函数的索引(尽管您希望包含显式 TO_NUMBER 或与字符串而不是数字进行比较以避免隐式转换)。但是,复合索引可能是维护效率最低的(尽管我们在这里讨论的是相对较小的差异),并且在我看来是最不干净的索引替代品。

    【讨论】:

    • 如果没有完整的典型查询列表,很难预测索引效率。
    猜你喜欢
    • 2022-07-11
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多