我们有一个6B行表,在检索数据时给我们带来了挑战。
我们的查询在执行...
时立即返回值as_completed
这种即时结果正是我们所需要的。我们现在想过滤以接收特定年份的值 - 但是我们添加的那一刻......
SELECT * WHERE Event_Code = 102225120
...查询需要10分钟才能开始返回任何值。
Another SO post提到索引在拉动多行而不是单个行时不一定有助于查询日期。还有其他方法,如使用TRUNC或BETWEEN,或指定YYYY-MM-DD格式的日期时间进行比较。
值得注意的是,我们没有选择向数据库添加索引,因为它是供应商的数据库。
添加日期过滤查询并使Oracle能够以最快的方式开始流式传输结果的方法是什么?
答案 0 :(得分:1)
另一篇SO帖子提到索引在拉动多行而不是单行时必然有助于查询日期
这个问题与你的问题完全不同。首先,您的上述声明适用于任何数据类型,而不仅仅是日期。此词很多也与表格中的记录数量有关。如果优化程序确定查询将返回表中所有记录的很多,那么它可能会确定对表的完整扫描比使用索引更快。在您的情况下,这会转换为表中所有记录中2017年的记录数量?此计算为您提供查询的基数,然后您可以了解索引是否更快。
现在,如果您决定索引会更快,基于上述内容,下一步就是知道如何构建索引。为了使优化器使用索引,它必须与您正在使用的条件匹配。您没有比较查询中的日期,而只是比较年份部分。因此,此查询不会使用日期列的索引。您需要在年份部分创建索引,因此请使用相同的条件来创建索引。
我们没有选择将索引添加到数据库,因为它是供应商的数据库。
如果无法修改数据库,则无法优化查询。您需要与供应商交谈并获得修改数据库的权限,或要求他们为您添加索引。
答案 1 :(得分:1)
函数也会导致所涉及的记录数量变慢。不确定基于功能的索引是否可以帮助您,但您可以尝试。
您是否曾尝试在表格中添加年份列?如果没有,请尝试添加年份列并使用以下代码进行更新。
UPDATE table
SET year = EXTRACT(YEAR FROM PERFORMED_DATE_TIME);
这需要时间。
但在此之后,您可以运行以下查询。
SELECT *
FROM table
WHERE Event_Code = 102225120 AND year = 2017;
另外,请尝试考虑Table Partitioned这个大数据。首先,请参阅下面的链接,
link:https://oracle-base.com/articles/8i/partitioned-tables-and-indexes
答案 2 :(得分:0)
你的问题有点模糊恕我直言:
但是我们添加的那一刻...... 和提取(年度来自PERFORMED_DATE_TIME)= 2017年 ...查询需要10分钟才能开始返回任何值。
你的意思是
SELECT * WHERE Event_Code = 102225120
很快,但是
SELECT * WHERE Event_Code = 102225120 AND EXTRACT(YEAR FROM PERFORMED_DATE_TIME) = 2017
很慢???
对于初学者,我同意Mitch Wheat,你应该尝试在2017年1月1日到2017年12月31日之间使用PERFORMED_DATE_TIME
而不是年份(字段)= 2017.即使你有一个索引在球场上,后者几乎无法利用它,而第一种方法将大大受益。
我也希望你想要更具体而不仅仅是“给我2017年的全部时间”,因为返回超过1B行绝对不会很快。
接下来,如果您无法对数据库进行更改,您是否能够在另一个数据库中维护“阴影”?这将要求您在另一个数据库中创建一个包含所有日期值和原始表的PK的表,并查询这些表以查找相关的PK值,然后将这些值重新连接到原始表以查找所需的任何内容。最大的问题是你需要保持阴影与原始表同步。如果您知道原始表只在一夜之间更改,您可以在早上合并更改并查询整天。如果应用程序是“实时(ish)”,那么如果没有一些聪明的想法,这可能是行不通的......是的,你初始加载的6B值会相当沉重=)
答案 3 :(得分:0)
这可能是有用的(因为你避免了函数(上下文切换的原因),如果你的日期字段有索引,可以使用它):
with
dt as
(
select
to_date('01/01/2017', 'DD/MM/YYYY') as d1,
to_date('31/01/2017', 'DD/MM/YYYY') as d2
from dual
),
dates as
(
select
dt.d1 + rownum -1 as d
from dt
connect by dt.d1 + rownum -1 <= dt.d2
)
select *
from your_table, dates
where dates.d = PERFORMED_DATE_TIME
答案 4 :(得分:-1)
将日期文字移动到RHS:
AND PERFORMED_DATE_TIME >= date '2017-01-01'
AND PERFORMED_DATE_TIME < date '2018-01-01'
但如果PERFORMED_DATE_TIME
没有(未公开的)适当的索引,查询就不会更快。
在第三方数据库中创建索引的一个选项是在索引中编写脚本,然后在任何供应商升级之前运行脚本以删除您添加的任何索引。如果索引很重要,请要求供应商将其添加到数据库设计中。