[20181123]关于降序索引问题.txt

[20181123]关于降序索引问题.txt


--//以前写的链接:http://blog.itpub.net/267265/viewspace-1159181/

--//降序索引实际上dump值的每个值与0xff异或,最后添加0xff.这样索引键值长度比普通索引长度+1.

--//NULL实际上对应0xff,这样异或后变成0x00.


--//有几个疑问.1.如果字符串长度已经是4000字符如何处理.2.如果插入chr(0),对应键值是0xff吗?

--//还是通过测试说明问题:


1.环境:

SCOTT@book> @ ver1

PORT_STRING                    VERSION        BANNER

------------------------------ -------------- --------------------------------------------------------------------------------

x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production


2.建立测试:


create table t (id number,name varchar2(4000)); 

insert into t values (1,'aaaaaa'); 

insert into t values (2,'bbbbbb'); 

insert into t values (3,chr(0)); 

insert into t values (4,lpad('c',4000,'c')); 

commit ;

create  index i_t_name on t(name desc); 


SCOTT@book> select segment_name,header_file,header_block from dba_segments where owner=user and segment_name in ('I_T_NAME');

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

-------------------- ----------- ------------

I_T_NAME                       4          554


--//记录很少,仅仅只有一个索引根节点。


SCOTT@book> alter system dump datafile 4 block 555;

System altered.


3.检查转储:


Block header dump:  0x0100022b

 Object id on Block? Y

 seg/obj: 0x1610c  csc: 0x03.376e0cf9  itc: 2  flg: E  typ: 2 - INDEX

     brn: 0  bdba: 0x1000228 ver: 0x01 opc: 0

     inc: 0  exflg: 0


 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

0x02   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0003.376e0cf9

Leaf block dump

===============

header address 140469718254180=0x7fc1a7a88264

kdxcolev 0

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y

kdxconco 2

kdxcosdc 0

kdxconro 4

kdxcofbo 44=0x2c

kdxcofeo 3974=0xf86

kdxcoavs 3930

kdxlespl 0

kdxlende 0

kdxlenxt 0=0x0

kdxleprv 0=0x0

kdxledsz 0

kdxlebksz 8032

row#0[4021] flag: ------, lock: 0, len=4011

col 0; len 4000; (4000):

 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c

 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c

...

 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c 9c

--//可以发现如果字符串长度等于4000,后面的0xff不存在.

col 1; len 6; (6):  01 00 02 24 00 03

row#1[4004] flag: ------, lock: 0, len=17

col 0; len 7; (7):  9d 9d 9d 9d 9d 9d ff

col 1; len 6; (6):  01 00 02 24 00 01

row#2[3987] flag: ------, lock: 0, len=17

col 0; len 7; (7):  9e 9e 9e 9e 9e 9e ff

col 1; len 6; (6):  01 00 02 24 00 00

row#3[3974] flag: ------, lock: 0, len=13

col 0; len 3; (3):  fe fe ff

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

col 1; len 6; (6):  01 00 02 24 00 02

----- end of leaf block dump -----

End dump data blocks tsn: 4 file#: 4 minblk 555 maxblk 555


SCOTT@book> select dump(name,16) c30 from t where id <=3;

C30

------------------------------

Typ=1 Len=6: 61,61,61,61,61,61

Typ=1 Len=6: 62,62,62,62,62,62

Typ=1 Len=1: 0


--//奇怪的是chr(0),降序排序后变成了fe fe ff.长度变成了3.看来我以前想的过于简单了.


SCOTT@book> create  index i_t_namex on t(name);

Index created.


SCOTT@book> select segment_name,header_file,header_block from dba_segments where owner=user and segment_name in ('I_T_NAMEX');

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

-------------------- ----------- ------------

I_T_NAMEX                      4          562


SCOTT@book> alter system dump datafile 4 block 563;

System altered.


Block header dump:  0x01000233

 Object id on Block? Y

 seg/obj: 0x1610e  csc: 0x03.376e112c  itc: 2  flg: E  typ: 2 - INDEX

     brn: 0  bdba: 0x1000230 ver: 0x01 opc: 0

     inc: 0  exflg: 0


 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

0x02   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn 0x0003.376e112c

Leaf block dump

===============

header address 140469718254180=0x7fc1a7a88264

kdxcolev 0

KDXCOLEV Flags = - - -

kdxcolok 0

kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y

kdxconco 2

kdxcosdc 0

kdxconro 4

kdxcofbo 44=0x2c

kdxcofeo 3978=0xf8a

kdxcoavs 3934

kdxlespl 0

kdxlende 0

kdxlenxt 0=0x0

kdxleprv 0=0x0

kdxledsz 0

kdxlebksz 8032

row#0[8021] flag: ------, lock: 0, len=11

col 0; len 1; (1):  00

col 1; len 6; (6):  01 00 02 24 00 02

row#1[8005] flag: ------, lock: 0, len=16

col 0; len 6; (6):  61 61 61 61 61 61

col 1; len 6; (6):  01 00 02 24 00 00

row#2[7989] flag: ------, lock: 0, len=16

col 0; len 6; (6):  62 62 62 62 62 62

col 1; len 6; (6):  01 00 02 24 00 01

row#3[3978] flag: ------, lock: 0, len=4011

col 0; len 4000; (4000):

 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63

...

 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63

col 1; len 6; (6):  01 00 02 24 00 03

----- end of leaf block dump -----

End dump data blocks tsn: 4 file#: 4 minblk 563 maxblk 563


3.重新测试:

create table tx (id number,name varchar2(10)); 

insert into tx values (0,chr(0)); 

insert into tx values (1,chr(1)); 

insert into tx values (2,chr(2)); 

insert into tx values (3,chr(97)); 

commit ;


SCOTT@book> create  index if_tx_name on tx(name desc,name);

Index created.


SCOTT@book> select segment_name,header_file,header_block from dba_segments where owner=user and segment_name in ('IF_TX_NAME');

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

-------------------- ----------- ------------

IF_TX_NAME                     4          682


SCOTT@book> alter system flush buffer_cache;

System altered.


SCOTT@book> alter system dump datafile 4 block 683;

System altered.


--//检查转储:

row#0[8018] flag: ------, lock: 0, len=14

col 0; len 2; (2):  9e ff

col 1; len 1; (1):  61

col 2; len 6; (6):  01 00 02 a4 00 03

row#1[8004] flag: ------, lock: 0, len=14

col 0; len 2; (2):  fd ff

col 1; len 1; (1):  02

col 2; len 6; (6):  01 00 02 a4 00 02

row#2[7989] flag: ------, lock: 0, len=15

col 0; len 3; (3):  fe fa ff

col 1; len 1; (1):  01

col 2; len 6; (6):  01 00 02 a4 00 01

row#3[7974] flag: ------, lock: 0, len=15

col 0; len 3; (3):  fe fe ff

col 1; len 1; (1):  00

col 2; len 6; (6):  01 00 02 a4 00 00


--//要表达chr(0)为什么是fe fe,真是再次考验自己的中文表达能力^_^.


1.首先1点为什么最后加上0xff,实际上为了排序的需要,假设2个字符串排序'a','aa',如果正常排序'a','aa'.

  降序排序就是'aa'在前,'a'在后.如果没有0xff在最后,'aa'=>'0x9e9e','a'=>'0x9e',这样排序变成'a'在前,'aa'在后.

  最后补上'0xff'后,'保证'a'在'aa'之后(指编码之后).aa'=>'0x9e9eff','a'=>'0x9eff',这样降序排序保证'aa'在前,'a'在后.因为

  0xff是最大的ascii码.  这也是为什么降序排序最后要加上0xff.


2.这样问题就来了,假设排序字符串'a\0'(实际上就是'a'||chr(0)).这样如果按照前面的编码问题就来了.

  'a\0'对应编码就是'0x9effff','a'=>'0x9eff'.这样降序排序有变成了'a'在前,'a\0'在后,违背降序排序的原则.

  为了规避这个风险,oracle选择'0xfefe'表示chr(0)的降序.这样chr(1)就不能再是'0xfe',变成了'0xfefa',

  至于为什么不是'0xfefd','0xfefc',我就不知道了.


--//另外实际上降序使用的函数是sys_op_descend,反向是SYS_OP_UNDESCEND,可以通过执行计划看出来.


SCOTT@book> select /*+ index(t) */ count(*) from tx where name=chr(0);

  COUNT(*)

----------

         1


SCOTT@book> @ dpc '' ''

PLAN_TABLE_OUTPUT

-------------------------------------

SQL_ID  4t3j0dhf5qg2c, child number 0

-------------------------------------

select /*+ index(t) */ count(*) from tx where name=chr(0)

Plan hash value: 4016183490

---------------------------------------------------------------------------------

| Id  | Operation         | Name       | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |

---------------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |            |        |       |     1 (100)|          |

|   1 |  SORT AGGREGATE   |            |      1 |     7 |            |          |

|*  2 |   INDEX RANGE SCAN| IF_TX_NAME |      1 |     7 |     1   (0)| 00:00:01 |

---------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):

-------------------------------------------------------------

   1 - SEL$1

   2 - SEL$1 / TX@SEL$1

Predicate Information (identified by operation id):

---------------------------------------------------

   2 - access("TX"."SYS_NC00003$"=HEXTORAW('FEFEFF') )

       filter(SYS_OP_UNDESCEND("TX"."SYS_NC00003$")=')


--//执行计划实际上包括access以及filter.


SCOTT@book> select sys_op_descend(chr(rownum-1)) from dual connect by level<=8;

SYS_OP_D

--------

FEFEFF

FEFAFF

FDFF

FCFF

FBFF

FAFF

F9FF

F8FF

8 rows selected.


SCOTT@book> select SYS_OP_UNDESCEND('FEFEFF') from dual ;

SY

--

00


SCOTT@book> select SYS_OP_UNDESCEND('FEFDFF') from dual ;

SYS_

----

0000


SCOTT@book> select SYS_OP_UNDESCEND('FEFCFF') from dual ;

SYS_

----

0001


SCOTT@book> select SYS_OP_UNDESCEND('FEFAFF') from dual ;

SY

--

01

--//这样大家明白为什么chr(1)是'0xFEFA'吧,大家自己细细体会吧,不再写出来了,真心不好写.


总结:

--//真心佩服oracle的一些设计细节,真是博大精深.


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-2221425/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/267265/viewspace-2221425/

Reeds-Shepp曲线公式推导及代码实现-第三部分(共三部分) 根据原始起点的坐标和航向,将上一小节计算出来的局部进行整体的平移和旋转(与归一化的步骤刚好相反),最终得到全局路径的轨迹。根据计算出来的路径,选择路径最短的轨迹(也可根据我们实际的需要定制选优规则),作为最终的轨迹输出。Reeds-Shepp曲线公式推导及代码实现-第一部分(共三部分)Reeds-Shepp曲线公式推导及代码实现-第二部分(共三部分)的值进行等步长插值,得到每段轨迹对应的生成一系列插值距离列表。根据上一步生成的插值距离列表的值,计算其对应的局部位姿值。后,我们需要根据字段类型( 阅读详情

相关推荐

基于Arduino与Velostat的智能鞋垫:DIY足底压力监测系统全解析

压力传感器是物联网和健康监测领域的基础元件,其核心原理是将物理压力转换为可测量的电信号。通过压阻效应,材料的电阻值随压力变化,从而实现压力感知。这项技术为低成本、定制化的健康监测方案提供了可能,尤其在运动分析和康复训练中具有重要价值。本文聚焦于利用Velostat压敏材料和Arduino平台,详细解析如何从传感器制作、信号调理到无线数据传输,构建一套完整的足底压力监测系统。文中深入探讨了传感器阵列构建、信号滤波等关键技术,并针对常见问题提供了实用的解决方案,为创客和开发者实现可穿戴健康监测设备提供了清晰的工

weixin_32818781的博客 363

oracle逗号拼接参数支持in查询,请教:降序索引不能支持in(两个参数以上)查询?有理论依据或相似案例吗?...

--搞了4个全表扫描,说明oracle是想走的,但是估计内部代码BUG,导致事实没有走,还触发了BUGSQL> show releaserelease 1102000100SQL> SELECT/*+OR_EXPAND(m object_name) index(m)*/object_name FROM m WHERE object_name IN ('A','B');执行计划---...

weixin_35473217的博客 152

医院批量排班实战指南(三)日期列表生成与时段批量操作

在上一篇《批量排班功能实现指南(二):日期与时段设置》中,我们完成了日期范围选择和重复规则配置的界面搭建,实现了从第一步到第二步的跳转功能。现在我们已经可以选择日期范围和重复规则,但还缺少最关键的功能——根据规则生成日期列表并进行时段配置。本篇将继续深入批量排班的核心功能——日期列表生成与时段批量操作。根据日期范围和重复规则智能生成日期列表为每个日期配置上午、下午、夜诊时段批量时段操作提升配置效率日期列表的展示与管理。

低代码布道师的博客 1317

降序索引浅析

--降序索引 EODA@PROD1> drop table t purge; Table dropped. EODA@PROD1> set echo on EODA@PROD1> create table t as select * from all_objects; Table created. EODA@PROD1> create index t_idx on t(owner,obj

blockheading的博客 1428

oracle 降序索引

创建数据:

天元喜羊羊的博客 4385

一条简单的sql在11g和12c中的不同

今天在查看awr报告的时候,有一句很简单的sql语句引起了我的注意,因为它排在SQL Order by Reads的第2位。 Physical Reads ...

congbao6525的博客 280

《Oracle编程艺术》学习笔记(30)-B*树索引

B*树索引是Oracle的“传统“索引。 B*树的构造类似于二叉树,能根据键提供一行或一个行集的快速访问,通常只需很少的读操作就能找到正确的行。 不过,”B*树“中的”B“不代表二叉(binary),而代表平衡(balanced)。B*树索引并不是一颗二叉树。在一个数字列上建立的索引类似于下图: 叶子节点之上的内部块称为分支块(branch block)。这些节点用于在结构中实现导航。 最...

suoyihen 172

oracle11g查看数据库名称,oracle11g系列 事物和常用数据库对象

1.1. 事务事务就是业务上的一个逻辑单元,它能够保证其中对数据所有的操作会全部成功,要么全部失败。事务开始于一条可执行的SQ语句,继续执行事务主题,然后结束于以下的任意一种情况。显示提交(COMMIT):当事务遇到COMMIT指令时,将结束事务并永久保存所有所有更改的数据。显示回滚(ROLLBACK):当事务遇到ROLLBACK指令时,也将结束事务的执行,但是此时它回滚所有更改的数据到事务开始时...

weixin_39616503的博客 1003

[20181124]关于降序索引问题3.txt

[20181124]关于降序索引问题3.txt --//链接:blog.itpub.net/267265/viewspace-2221425/,探讨降序索引索引的键值。 --//实际上使用函数sys_o...

187

oracle 索引的创建与管理

索引的相关创建与使用 创建普通索引 SQL> select * from temp; ...

196

Oracle 编程艺术--降序索引读书笔记

1. 11gr2数据库索引默认排序是asc,不是desc。       准备测试数据  create table test as select rownum as objectid,object_name from all_objects;       创建默认索引 create index idx_objectid_test on test(objectid);      select

bruce_wang_janet的专栏 1115

错误的转换绑定变量类型导致执行计划错误

昨天开发来问我个问题,一个业务sql执行缓慢,下面 SQL> SELECT A.ISSUE_OID,       (SELECT B.ISSUE_END_TIME FROM ISSUE_T B WHERE A.ISSUE_OID = B.IWOID) AS ISSUE_END_TIME,       (SELECT C.ENCASH_END_TIME FROM ISSUE_T C WHERE

wujizhou的专栏 669

oracle如何按时间索引降序,oracle 降序索引

创建数据:SQL> create table tb_desc_index2 (3 user_year int not null,4 user_month int not null,5 user_date int not null,6 user_name varchar2(20) null7 );表已创建。SQL> DECLARE2 V...

weixin_39939276的博客 919

10205 bug之6980350, dbms_stats巨慢无比

OS: HP DB: 10204升级至10205 症状: 升级完成后,客户开始抱怨数据库跑的很慢,以前几个小时能跑完的job现在需要10几个小时,一天能搞定的现在则需要好几天。 ...

congdiku5262的博客 265

oracle中查看执行计划常用的方法

本文介绍了oracle中查看执行计划常用的方法。 1、EXPLAIN PLAN命令 2、AUTOTRACE开关 3、DBMS_XPLAN 4、10046事件 1、EXPLAIN PLAN命...

cty48663的博客 365

[20181124]关于降序索引问题2.txt

[20181124]关于降序索引问题2.txt --//链接:blog.itpub.net/267265/viewspace-2221425/,探讨降序索引索引的键值。 --//实际上使用函数sys_o...

177

min max and page

棉花糖ONE 2009年03月11日 19:57 阅读(51) 评论(1) 分类:个人日记 权限: 公开 字体:大▼ 小 中 大 更多▼ 设置置顶 权限设置 推荐日志 转为私密日志 删除编辑1.最大值和最小值,如果从索引结构上来...

ck0210的博客 338

软件工厂设计模式:多智能体协作与流水线编排实践

设计模式作为软件工程中解决特定问题的经典范式,长期指导着代码结构设计。当AI Agent协作场景日益复杂,传统的类级模式已难以应对多智能体间任务分工、制品流转与失败兜底等编排难题。软件工厂设计模式将工业流水线理念引入智能体协作,通过工位、制品、质检与线长等角色定义,把任务拆解为标准化阶段,建立可观测、可追溯的流程。该模式的核心价值在于,不依赖单个模型的智能程度,而是通过明确的输入输出契约、角色边界和重试机制,提升整体系统的稳定性和工程化水平。无论是批量内容生产、代码自动修复还是客服工单处理,这种模式都能帮助

520

使用B*Tree索引的情况简析

--使用B*Tree索引的情况简析 --什么情况下使用 --1.如果你要访问表中非常少的一部分数据。 -->通过读索引来访问表中的数据,前提是当问的数据只占表的很小一部分。 --2.如果你要处理表中的大量数据,但这些数据可以通过索引直接拿到。索引包含了足够的信息来回答整个查询,我们根本不用去访问整个表。 1. EODA@PROD1> set autotrace traceonly expla

blockheading的博客 384

ERP 销售出库单查询---出库单明细 SQL优化

其实一直都觉得咋们ERP查询 这一块挺慢的,不过这为我学习优化SQL提供了很好的实践机会。下面来记录下我的这次优化。其实这次SQL优化成功还要源自落落博客的一文章,让我找到了优化入口。 select a.APPROVALNO,a.QUALITYSTATENAME,a.ENTIREQUANTITY,c.printcount,a.billid,a.branchid,a.pk,a.billingd

生如夏花 4138

oracle 索引降序及排序条件 对查询计划的影响

创建一个常规的堆表,并在上面建一个复合索引SQL> create table t1 as select * from all_objects;表已创建。SQL> create index idx_t1_1 on t1...

cuijianli8434的博客 527

oracle 降序索引 创建,降序索引应用在Top N问题上的应用

SQL> create table test_desc (id number not null,name varchar2(16)) tablespace users;Table created.SQL> create index test_id_desc_idx on test_desc(id desc) tablespace idx;Index created.Oracle默认情况...

weixin_34378888的博客 418
上一篇: [20181123]快速提升scn注意.txt
下一篇: [20181124]关于降序索引问题2.txt
cuixun7780
博客等级 码龄10年 6粉丝 673原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值