[20181124]關於降序索引問題2.txt
[20181124]關於降序索引問題2.txt
--//連結:blog.itpub.net/267265/viewspace-2221425/,探討降序索引中索引的鍵值。
--//實際上使用函式sys_op_descend.
--//前面已經提到結尾加入FF,為了排序的需要。這樣導致chr(0),以及後續的chr(1)字元出現問題。
--//一些細節繼續探究:
1.環境:
[email protected]> @ ver1
PORT_STRING VERSION BANNER CON_ID
-------------------- ---------- ---------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.2.0.1.0 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
2.測試:
2 AS (SELECT '00' a, CHR (0) b FROM DUAL
3 UNION ALL
4 SELECT '01', CHR (1) FROM DUAL)
5 SELECT x1.a c10, sys_op_descend (x1.b) c20
6 FROM x0 x1;
C10 C20
---------- --------------------
00 FEFEFF
01 FEFAFF
2 AS (SELECT '00' a, CHR (0) b FROM DUAL
3 UNION ALL
4 SELECT '01', CHR (1) FROM DUAL)
5 SELECT x1.a || x2.a c10, sys_op_descend (x1.b || x2.b) c20
6 FROM x0 x1, x0 x2;
C10 C20
---------- --------------------
0000 FEFDFF
0001 FEFCFF
0100 FEF9FF
0101 FEF8FF
--//注意以上編碼。繼續測試:
WITH x0
AS (SELECT '00' a, CHR (0) b FROM DUAL
UNION ALL
SELECT '01', CHR (1) FROM DUAL
union all
SELECT '02', CHR (2) FROM DUAL
)
SELECT x1.a || x2.a c10, sys_op_descend (x1.b || x2.b) c20
FROM x0 x1, x0 x2;
C10 C20
---------- --------------------
0000 FEFDFF
0001 FEFCFF
0002 FEFBFDFF
0100 FEF9FF
0101 FEF8FF
0102 FEF7FDFF
0200 FDFEFEFF
0201 FDFEFAFF
0202 FDFDFF
9 rows selected.
--//不看結尾的ff。可以看出編碼的規律
--//字串0x00,0x0000,0x0001,0x00NN(0xNN>=0x02),0x01,0x0100,0x0101,0x01NN(0xNN>=0x02) 單獨編碼。畫一個表格:
ascii碼 編碼
---------------------------------------------
0x00 FEFE
0x0000 FEFD
0x0001 FEFC
0x00NN(0xNN>=0x02) FEFB
0x01 FEFA
0x0100 FEF9
0x0101 FEF8
0x01NN(0xNN>=0x02) FEF7
---------------------------------------------
--//看一個複雜一點的例子:
WITH x0
AS (SELECT '00' a, CHR (0) b FROM DUAL
UNION ALL
SELECT '01', CHR (1) FROM DUAL
UNION ALL
SELECT '02', CHR (2) FROM DUAL)
SELECT x1.a || x2.a || x3.a c10
,sys_op_descend (x1.b || x2.b || x3.b) c20
,TO_CHAR (ASCII ('z'), 'FMXX') || x1.a || x2.a || x3.a c10
,sys_op_descend ('z' || x1.b || x2.b || x3.b) c20
FROM x0 x1, x0 x2, x0 x3;
C10 C20 C10 C20
---------- -------------------- ---------- --------------------
000000 FEFDFEFEFF 7A000000 85FEFDFEFEFF
000001 FEFDFEFAFF 7A000001 85FEFDFEFAFF
000002 FEFDFDFF 7A000002 85FEFDFDFF
000100 FEFCFEFEFF 7A000100 85FEFCFEFEFF
000101 FEFCFEFAFF 7A000101 85FEFCFEFAFF
000102 FEFCFDFF 7A000102 85FEFCFDFF
000200 FEFBFDFEFEFF 7A000200 85FEFBFDFEFEFF
000201 FEFBFDFEFAFF 7A000201 85FEFBFDFEFAFF
000202 FEFBFDFDFF 7A000202 85FEFBFDFDFF
010000 FEF9FEFEFF 7A010000 85FEF9FEFEFF
010001 FEF9FEFAFF 7A010001 85FEF9FEFAFF
010002 FEF9FDFF 7A010002 85FEF9FDFF
010100 FEF8FEFEFF 7A010100 85FEF8FEFEFF
010101 FEF8FEFAFF 7A010101 85FEF8FEFAFF
010102 FEF8FDFF 7A010102 85FEF8FDFF
010200 FEF7FDFEFEFF 7A010200 85FEF7FDFEFEFF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
010201 FEF7FDFEFAFF 7A010201 85FEF7FDFEFAFF
010202 FEF7FDFDFF 7A010202 85FEF7FDFDFF
020000 FDFEFDFF 7A020000 85FDFEFDFF
020001 FDFEFCFF 7A020001 85FDFEFCFF
020002 FDFEFBFDFF 7A020002 85FDFEFBFDFF
020100 FDFEF9FF 7A020100 85FDFEF9FF
020101 FDFEF8FF 7A020101 85FDFEF8FF
020102 FDFEF7FDFF 7A020102 85FDFEF7FDFF
020200 FDFDFEFEFF 7A020200 85FDFDFEFEFF
020201 FDFDFEFAFF 7A020201 85FDFDFEFAFF
020202 FDFDFDFF 7A020202 85FDFDFDFF
27 rows selected.
--//我僅僅分析下劃線記錄.遇到00,01需要上面的特殊編碼。
--//010200,變成01,02,00 ,0102 對應的就是01NN,02編碼,這樣就是FEF7,FD.剩下的00 對應編碼就是 FEFE。
--//這樣010200 對應編碼就是 FEF7 FD FEFE FF 。
--//7A010200,變成 7A,01,02,00 , 7A與FF異或= 85, 01對應編碼要結合後面的02,
--//0102 對應的就是01NN,02編碼,這樣就是FEF7,FD.剩下的00 對應編碼就是 FEFE。
--//這樣7A010200 對應編碼就是 85 FEF7 FD FEFE FF.
3.總結:
--//總之一點就是排序的需要,跳出1個坑(結尾加FF),又進入一個更深的坑chr(0),佔用chr(1)的編碼,又進入一個更深的坑。
--//結果出現這樣特殊的編碼,實際上也給一些開發提供一些借鑑,看看oracle技術人員如何實現這些,雖然不知道該如何
--//寫這些程式碼。
--//如果應用程式就不會考慮這樣的情況,但是對於oracle這樣的資料庫軟體,必須注意這些細節,導致編碼發熱複雜性.
--//我自己花了一個晚上,才從中總結出規律,又有點鑽牛角尖了。^_^。