【问题标题】:query takes longer time to execute even if index are created即使创建了索引,查询也需要更长的时间来执行
【发布时间】:2020-05-22 11:38:30
【问题描述】:

我有一个表DB_TBL,其中历史数据在每个月的 5 日从工具中插入。作为其历史数据,插入的行数非常大。例如,我检查了本月的计数及其 1626521。

此表包含 50 列。但我有兴趣只检查 5 列。前端有 gui 使用这 5 列,我在其中提供过滤器以每次获取一个月数据,例如上个月的 01.01.2020 和 31.01.2020 之间的closure_date。

Select Client_key, Portfolia_Name, Closure_date, 
    Currency_Type, Balance from DB_TBL        
    where CLOSURE_DATE between 
    to_date ('01.01.2020','dd.mm.yyyy') and to_date ('31.01.2020','dd.mm.yyyy');

此查询非常慢,运行时间超过 30 分钟。这个问题与我在 gui 中遇到的相同问题非常关键。我已经为Closure_date 列提供了索引。但它仍然没有提高性能。

有什么方法可以提高查询性能?可能我可以创建Virtual based index 或创建View 吗?

【问题讨论】:

  • 发布您的表定义。
  • 您如何衡量绩效?这是实际的查询执行时间还是包括 GUI 渲染?
  • 两种方式都需要很多时间..从 gui 我正在从这些数据创建 csv 作为报告的一部分
  • 我的意思是,您是否在数据库查询工具中自行运行此查询并检查性能?
  • 是的,我在 db Visualizer 中运行并检查了性能

标签: sql oracle indexing query-performance


【解决方案1】:

首先,我将使用日期文字编写查询:

Select Client_key, Portfolia_Name, Closure_date, Currency_Type, Balance
from DB_TBL
where CLOSURE_DATE between date '2020-01-01' and date '2020-01-31'

对于此查询,您需要db_tbl(closure_date) 上的索引。如果你已经有了这个索引,那么想必你有这么大的数据量,需要花费很多时间才能返回数据。您可以通过在索引中包含其余列(在CLOSURE_DATE 之后,应该是第一个)来将索引更改为覆盖索引。

也就是说,如果您想要 2020 年 1 月的所有数据,我建议:

where CLOSURE_DATE >= date '2020-01-01' and
      CLOSURE_DATE < date '2020-02-01'

这将返回所有行,即使是那些具有时间组件的行。这在 Oracle 中尤为重要,因为date 数据类型可以有一个时间组件——即使用户界面通常只显示日期。

【讨论】:

  • 如何将索引更改为覆盖索引?我需要在查询中显式创建或更改吗?
  • @Gordon Linoff - 我想澄清一些你说的我知道你理解但 OP 可能不理解的事情。您说“日期数据类型可以具有时间组件”(强调我的)。我知道您了解 DATE 数据类型确实有(不是可选的,如“可以有”所暗示的那样)时间组件。唯一的问题是时间分量的值是否为零(午夜)或其他值(大于午夜)。
  • @EdStevens 。 . .这是一个公平的评论。我倾向于将“午夜”视为date 的“正确”值。因此,我将午夜等同于“真实”日期。但您的解释在技术上更准确。
  • 您的意思是为我在查询中使用的任何列创建复合索引吗?在这种情况下创建分区也有帮助吗?
  • @Andrew 。 ..CLOSURE_DATE 分区可能有助于查询。不过我的猜测是,限制问题是返回数据的数量——除非你所说的“表”实际上是一个“视图”。
猜你喜欢
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多