范围分区跳过检查
我们有大量的数据使用 oracle 中的范围分区按年份值进行分区。我们使用了范围分区,但每个分区仅包含一年的数据。当我们编写针对特定年份的查询时,Oracle 会从该分区中获取信息,但仍会检查该年份是否是我们指定的年份。由于今年列不是索引的一部分,因此它从表中获取年份并进行比较。我们已经看到,每当查询获取表数据时,它都会变得太慢。
我们能否以某种方式避免 Oracle 比较年份值,因为我们确信分区只包含一年的信息。
更新:
执行分区的年份数据类型为number类型。
我们不会选择任何其他列。我只是执行
count(*)
并且没有选择任何列。如果我们删除条件并将查询定位到特定分区,如下所示
select count(*) from table_name partition(part_2004)
速度更快 尽管从表中选择计数(*) 其中year = 2004
要慢得多。分区位于年份列上,该列是一个数字,其操作如下
年份小于2005年part_2004
年份小于2006年part_2005
年份小于2007年part_2006
...依此类推
We have large amount of data partitioned on year value using range partition in oracle. We have used range partition but each partition contains data only for one year. When we write a query targeting a specific year, oracle fetches the information from that partition but still checks if the year is what we have specified. Since this year column is not part of the index it fetches the year from table and compares it. We have seen that any time the query goes to fetch table data it is getting too slow.
Can we somehow avoid oracle comparing the year values since we for sure know that the partition contains information for only one year.
Update:
The year data type on which partition is performed is of type number.
We are not selecting any additional columns. I am just performing a
count(*)
and no columns are being selected.If we remove the condition and target the query to specific partition as
select count(*) from table_name partition(part_2004)
it is faster
whileselect count(*) from table
is way slower.
where year = 2004The partition is on year column which is a number and is done something like below
year less than 2005 part_2004
year less than 2006 part_2005
year less than 2007 part_2006
...so on
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果没有解释计划或表定义,真的很难判断发生了什么。我的第一个猜测是您有 LOCAL 分区索引,没有
year
列。它们有助于分区上的 COUNT(*),但是当您查询单个年份时(至少在 10.2.0.3 上),它们似乎不会被使用。下面是一个重现您的发现(和解决方法)的小示例:
现在比较两个解释计划:
如您所见,当您直接查询年份时,不使用索引。当您将年份添加到 LOCAL 索引时,将使用它。我使用 COMPRESS 1 指令告诉 Oracle 压缩第一列。生成的索引几乎与原始索引大小相同(由于压缩),因此性能不会受到影响。
Without the explain plan or the table definition it's really hard to tell what goes on. My first guess is that you have LOCAL partitionned indexes without the
year
column. They help with the COUNT(*) on a partition, however they don't seem to be used when you query a single year (at least on 10.2.0.3).Here is a small example that reproduces your finding (and a workaround):
Now compare the two explain plans:
As you can see the index is not used when you query the year directly. When you add the year to the LOCAL index it will be used. I used the COMPRESS 1 instruction to tell Oracle to compress the first column. The resulting index is nearly the same size as the original index (thanks to compression) so performance shouldn't be impacted.
您确定它进入表只是为了检查年份吗?也许还涉及其他专栏?
该查询是否应该仅适用于(分区)索引?
如果无论如何都需要访问表,那么额外的检查不会花费太多(如果分区正确的话)。
你能发布查询和执行计划吗?
Are you sure that it goes to the table just for checking the year? Maybe there are other columns involved?
Was the query supposed to work only on (partitioned) indexes?
If it needs to go to the table anyway, that extra check is not costing much (if the partition is right).
Can you post the query and execution plan?