1. 程式人生 > >[20181124]關於降序索引問題2.txt

[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.測試:

[email protected]> WITH x0
  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

[email protected]
> WITH x0
  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這樣的資料庫軟體,必須注意這些細節,導致編碼發熱複雜性.
--//我自己花了一個晚上,才從中總結出規律,又有點鑽牛角尖了。^_^。