使用oracle中的范围分区,我们将大量数据按年值进行了分区。我们使用了范围分区,但每个分区仅包含一年的数据。当我们编写针对特定年份的查询时,oracle从该分区获取信息,但仍会检查年份是否是我们指定的年份。由于今年列不是索引的一部分,因此它从表中获取年份并进行比较。我们已经看到,每当查询去获取表数据时,它就会变得太慢。
我们可以以某种方式避免oracle比较年份值,因为我们确定知道分区仅包含一年的信息。
更新:
执行分区的年份数据类型为类型编号。
我们没有选择任何其他列。我只是执行一个,count(*)
并且没有选择任何列。
如果我们删除条件并将查询目标定位到特定分区, select count(*) from table_name partition(part_2004)
则它会更快,而 select count(*) from table where year = 2004
速度会更慢。
分区在年份列上,该列是一个数字,并执行以下操作
年,少于2005 part_2004
不足2006年的年份part_2005
年份,少于2007 part_2006
…很快
没有解释计划或表定义,很难说出发生了什么。我的第一个猜测是,您有没有该year
列的LOCAL分区索引。它们可以帮助您解决分区上的COUNT(*),但是当您查询单个年份(至少在10.2.0.3上)时似乎没有使用它们。
这是一个重现您的发现(和解决方法)的小示例:
SQL> CREATE TABLE DATA (
2 YEAR NUMBER NOT NULL,
3 ID NUMBER NOT NULL,
4 extra CHAR(1000)
5 ) PARTITION BY RANGE (YEAR) (
6 PARTITION part1 VALUES LESS THAN (2010),
7 PARTITION part2 VALUES LESS THAN (2011)
8 );
Table created
SQL> CREATE INDEX ix_id ON DATA (ID) LOCAL;
Index created
SQL> INSERT INTO DATA
2 (SELECT 2009+MOD(ROWNUM, 2), ROWNUM, 'A' FROM DUAL CONNECT BY LEVEL <=1e4);
10000 rows inserted
SQL> EXEC dbms_stats.gather_table_stats(USER, 'DATA', CASCADE=>TRUE);
PL/SQL procedure successfully completed
现在比较两个说明计划:
SQL> SELECT COUNT(*) FROM DATA WHERE YEAR=2010;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=197 Card=1 Bytes=4)
1 0 SORT (AGGREGATE)
2 1 PARTITION RANGE (SINGLE) (Cost=197 Card=5000 Bytes=20000)
3 2 TABLE ACCESS (FULL) OF 'DATA' (TABLE) (Cost=197 Card=5000...)
SQL> SELECT COUNT(*) FROM DATA PARTITION (part1);
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=11 Card=1)
1 0 SORT (AGGREGATE)
2 1 PARTITION RANGE (SINGLE) (Cost=11 Card=5000)
3 2 INDEX (FULL SCAN) OF 'IX_ID' (INDEX) (Cost=11 Card=5000)
如您所见,直接查询年份时 不 使用索引。将年份添加到本地索引时,将使用该年份。我使用COMPRESS
1指令告诉Oracle压缩第一列。结果索引的大小几乎与原始索引相同(由于压缩),因此性能不应受到影响。
SQL> DROP INDEX ix_id;
Index dropped
SQL> CREATE INDEX ix_id ON DATA (year, ID) LOCAL COMPRESS 1;
Index created
SQL> SELECT COUNT(*) FROM DATA WHERE YEAR=2010;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=12 Card=1 Bytes=4)
1 0 SORT (AGGREGATE)
2 1 PARTITION RANGE (SINGLE) (Cost=12 Card=5000 Bytes=20000)
3 2 INDEX (RANGE SCAN) OF 'IX_ID' (INDEX) (Cost=12 Card=5000...)
问题内容: 我想查询日期范围内的elasticsearch文档。我现在有两个选择,两个都适合我。已经测试了他们两个。1.范围查询2.范围过滤器 由于我现在的数据集很小,因此无法测试它们的性能。两者有什么区别?哪个会导致更快地检索文档和更快地响应? 问题答案: 查询和过滤器之间的主要区别在于评分。查询将返回每个文档具有相对排名得分的文档。过滤器没有。这种差异使过滤器更快,有两个原因。首先,它不会产生
[新加入Spark]语言-Scala 根据文档,RangePartitioner对元素进行排序并将其划分为块,然后将块分发到不同的机器。下面的例子说明了它是如何工作的。 假设我们有一个数据框,有两列,一列(比如“a”)的连续值从1到1000。还有另一个数据帧具有相同的模式,但对应的列只有4个值30、250、500、900。(可以是任意值,从1到1000中随机选择) 如果我使用RangePartit
问题内容: java中是否有一种优雅的方法来检查int是否等于或大于或小于1。 例如,如果我检查周围。我想在上返回true ,因为4和6距5仅1。 有内置功能可以做到这一点吗?还是我最好这样写? 当然,以上代码很难看懂。那有更好的方法吗? 问题答案: 找到它们之间的绝对差异 基于@GregS关于溢出的评论,如果您给出的差值不能适合整数,您将获得一个溢出值 通过将其中一个参数强制转换为long 将返
因此,我尝试使用Spark SQL进行以下查询('timestamp'是分区键): 虽然作业产生200个任务,但查询不会返回任何数据。 另外,我可以保证会返回数据,因为在cqlsh上运行查询(使用'token'函数进行适当的转换)确实会返回数据。 但不幸的是我不知道什么是“过滤器”...
两者都返回一个列表,那么到底有什么区别呢?
感谢所有人!