Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从索引中删除行ID,然后尝试按块访问行,以改进集群并减少数据库必须访问块的次数_Sql_Oracle_Sorting_Optimization_Indexing - Fatal编程技术网

Sql 从索引中删除行ID,然后尝试按块访问行,以改进集群并减少数据库必须访问块的次数

Sql 从索引中删除行ID,然后尝试按块访问行,以改进集群并减少数据库必须访问块的次数,sql,oracle,sorting,optimization,indexing,Sql,Oracle,Sorting,Optimization,Indexing,它通过减少命中每个块的次数来更有效地检索实际数据(假设实际数据分布意味着存在多行具有相关数据的块)。但结果是检索到的数据不一定按索引顺序排列,因此需要显式排序 当我们使用索引获取rowid时,我们将以相同的顺序从数据库中获取所有数据。这是我的期望 对于批处理的访问,情况不再如此 问题是,即使没有必要这样做,也会增加额外的成本 但这是必要的;而且,您没有看到成批访问带来的成本降低(如前所述,这取决于实际的数据分布)。你不能孤立地看待一个成本价值。乐观主义者通常知道它在做什么。(我认为这个暗示根本没

它通过减少命中每个块的次数来更有效地检索实际数据(假设实际数据分布意味着存在多行具有相关数据的块)。但结果是检索到的数据不一定按索引顺序排列,因此需要显式排序

当我们使用索引获取rowid时,我们将以相同的顺序从数据库中获取所有数据。这是我的期望

对于批处理的
访问,情况不再如此


问题是,即使没有必要这样做,也会增加额外的成本

但这是必要的;而且,您没有看到成批访问带来的成本降低(如前所述,这取决于实际的数据分布)。你不能孤立地看待一个成本价值。乐观主义者通常知道它在做什么。(我认为这个暗示根本没有影响到这一点,但我同意@XING的观点,即你不应该拥有它——除非你真的确定你知道乐观主义者不知道的事情)


值得注意的是,即使11g版本没有显示显式排序(根据@XING的演示),Oracle也从未保证订单结果将在没有
order by
子句的情况下返回,并且通过索引ROWID进行简单的
表访问(即非
批处理
)优化程序只是能够跳过显式排序,因为它已经知道数据是按该顺序检索的。这就是你在评论中提到的

在11g中,如果不使用
order by
子句,您可能会按照所需的顺序返回行,但这只是因为Oracle如何获取索引rowid,然后逐行获取相应数据的实现细节。但这并不能保证。这种暗箱操作的变化正是为什么即使看起来是多余的,也要明确地按
排序始终是明智的。正如您在当前代码中所做的那样。但这并不是多余的,也从来不是真的


(在早期版本中,group by也存在类似的“问题”;它通常意味着排序顺序(我想最多9次),人们忽略了
顺序,但后来乐观主义者改变了(我想是10g),这让人们被忽略了……)问题出在会话的
NLS\U语言
NLS\U区域
参数中。 默认情况下,我的会话

NLS\U语言=“俄语”

NLS_地区=“俄罗斯”

当我尝试在查询中使用varchar索引值和orderby按特定顺序获取数据时,我会在查询计划中获得额外的
排序依据

在我更改这些参数之后:

NLS\U语言='AMERICAN'

NLS\U地区=“美国”

在我的查询计划中,我没有获得额外的排序规则

现在,提问:

解释从SIEBEL_CT.A中选择*的计划,其中fieldB>按fieldB的“低”和“高”顺序

解释SIEBEL_CT.A中的select*计划,其中fieldB>为“低”字段,fieldB


具有相同的查询计划

问题在于会话的
NLS\U语言
NLS\U区域
参数。
explain plan for select /*+ index(a)*/ * from A a where fieldB > 'LOW' and fieldB < 'HIGH' order by fieldB
默认情况下,我的会话

NLS\U语言=“俄语”

NLS_地区=“俄罗斯”

当我尝试在查询中使用varchar索引值和orderby按特定顺序获取数据时,我会在查询计划中获得额外的
排序依据

在我更改这些参数之后:

NLS\U语言='AMERICAN'

NLS\U地区=“美国”

在我的查询计划中,我没有获得额外的排序规则

现在,提问:

解释从SIEBEL_CT.A中选择*的计划,其中fieldB>按fieldB的“低”和“高”顺序

解释SIEBEL_CT.A中的select*计划,其中fieldB>为“低”字段,fieldB


拥有相同的查询计划

您的查询中有ORDERBY子句,因此无法避免。如果您想避免,您需要从查询中删除
orderby
子句@XING,问题是我需要保证数据将按特定顺序返回。如果我按删除订单
,我将丢失此订单。但我的目标是通过使用默认的B-树索引升序来实现相同的逻辑,而不使用
orderby
。但这对我不起作用。所以,我不明白为什么优化器会选择重新排序数据,即使我希望返回的数据的顺序与生成索引的顺序相同。如果您只从查询中选择fieldB,会发生什么?@AllanS.Hansen,嗯,我按我想要的升序获取数据。但是,我如何才能在没有order by的情况下,不仅选择字段B,还选择其他字段?而且,如果我从order by fieldB asc中选择字段B,我将在查询计划中获得排序依据,但是我将以与不使用
orderby
相同的顺序获取数据,并且在查询计划中不使用任何排序子句查询中有orderby子句,因此无法避免。如果您想避免,您需要从查询中删除
orderby
子句@XING,问题是我需要保证数据将按特定顺序返回。如果我按删除订单
,我将丢失此订单。但我的目标是通过使用默认的B-树索引升序来实现相同的逻辑,而不使用orderby。但这对我不起作用。所以,我不明白为什么优化器会选择重新排序数据,即使我希望返回的数据的顺序与生成索引的顺序相同。如果您只从查询中选择fieldB,会发生什么?@AllanS.Hansen,嗯,我按我想要的升序获取数据。但是,我如何才能做到这一点呢
explain plan for select /*+ index(a)*/ * from A a where fieldB > 'LOW' and fieldB < 'HIGH' order by fieldB
explain plan for select /*+ index(a)*/ * from A a where fieldB > 'LOW' and fieldB < 'HIGH' order by fieldB
SELECT STATEMENT                     
SORT ORDER BY                       
TABLE ACCESS BY INDEX ROWID BATCHED
INDEX RANGE SCAN
create table A (
    fieldA numeric,
    fieldB varchar(255),
    fieldC varchar(255)
);

create index indx on A(fieldB);
select * from A a where fieldB > 'LOW' and fieldB < 'HIGH' order by fieldB ;
Plan Hash Value  : 4131509220 

--------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows | Bytes | Cost | Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |    1 |   271 |    0 |          |
| * 1 |   FILTER                       |      |      |       |      |          |
|   2 |    TABLE ACCESS BY INDEX ROWID | A    |    1 |   271 |    1 | 00:00:01 |
| * 3 |     INDEX RANGE SCAN           | INDX |    1 |       |    1 | 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter(NULL IS NOT NULL)
* 3 - access("FIELDB">'LOW' AND "FIELDB"<'HIGH')


Note
-----
- dynamic sampling used for this statement