《收获,不止Oracle》索引细化

news2024/9/28 13:17:16

1.索引知识图框

 2.索引探秘

 2.1 BTREE索引

索引是建在表的具体列上的,其存在的目的是让表的查询变得更快,效率更高。表记录丢失关乎生死,而索引丢失只需重建即可。

索引却是数据库学习中最实用的技术之一。谁能深刻地理解和掌握索引的知识,谁就能在数据库相关工作中事半功倍。在了解索引之前,我们需要先了解索引结构长什么样。

索引结构图

索引结构图说明索引是由Root(根块)、Branch(茎块)和Leaf(叶子块)三部分组成的,其中Leaf(叶子块)主要存储了key column value(索引列具体值),以及能具体定位到数据块所在位置的rowid(注意区分索引块和数据块)。

具体说说某个Oracle的索引查询吧,如:select * from t where id=12;,该t表的记录有10 050条,而id=12仅返回1条,在t表的id列上创建了一个索引,索引是如何快速检索到数据的呢?

首先查询定位到索引的根部,这是第1次IO;接下来根据根块的数据分布,定位到索引的茎部(查询到12的值的大致范围,在11..19的部分),这是第2次IO;然后定位到叶子块,找到 id=12的部分,此处为第3次 IO。假设 Oracle 在全表扫描记录,遍历所有的数据块,IO的数量必然将大大超过3次。有了这个索引,Oracle只会去扫描部分索引块,而非全部,少做事,必然能大大提升性能。

Leaf(叶子块)主要存储key column value(索引列具体值)以及能具体定位到数据块所在位置的rowid(注意区分索引块和数据块)。

2.2 到底是物理结构还是逻辑结构

物理结构可以理解为真正存在根、茎、叶的块。而逻辑结构可以理解为并没有存在根、茎的块,只是一种指针或者说一种内部算法。

1.要建索引先排序

未建索引的test表中的记录大致如图5-4所示,NULL表示该字段为空值,此外省略号表示略去不显示内容。注意rowid伪列,这是每一行的唯一标记,每一行的rowid 值绝对不重复,它可将行的记录定位到数据库中的位置。建索引后,将test表中id列的值按顺序取出放在内存中(这里需注意,除了id列的值外,还要注意取该列的值的同时,该行的rowid也被一并取出)。

2.列值入块成索引

依次将内存中顺序存放的列值和对应的rowid存进Oracle空闲的块中,形成索引块。

3.填满一块接一块

随着索引列的值的不断插入,index block1(L1)很快就被插满了。比如接下来取出的 id=9的记录无法插入index block1(L1)中,就只能插入新的块中,插入如图5-7所示的index block2(L2)。

4.同级两块需人管

随着叶子块的不断增加,B1块中虽然仅是存放叶子块的标记,但也挡不住量大,最终也容纳不下了。怎么办?接着装呗,到下一个块B2中去寻找空间容纳。

2.3 索引结构的三大重要特点

2.3.1.索引高度较低

2.3.2.索引存储列值

2.3.3.索引本身有序

索引的三大特点:

① 索引树的高度一般都比较低。

② 索引由索引列存储的值及rowid组成。

③ 索引本身是有序的。

索引从左向右看

2.4 妙用三特征之高度较低

2.4.1索引高度较低验证

① 构造一系列表t1到t6,记录数从5到50万依次以10倍的差额逐步增大


做索引高度较低试验前的构造表操作

SQL> show user
USER is "MAXWELLPAN"
SQL> drop table t1 purge;
drop table t1 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> drop table t2 purge;
drop table t2 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> drop table t3 purge;
drop table t3 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> drop table t4 purge;
drop table t4 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> drop table t5 purge;
drop table t5 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> drop table t6 purge;
drop table t6 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL>

SQL> create table t1 as select rownum as id,rownum+1 as id2 from dual connect by level<=5;

Table created.

SQL> create table t2 as select rownum as id,rownum+1 as id2 from dual connect by level<=50;

Table created.

SQL> create table t3 as select rownum as id,rownum+1 as id2 from dual connect by level<=500;

Table created.

SQL> create table t4 as select rownum as id,rownum+1 as id2 from dual connect by level<=5000;

Table created.

SQL> create table t5 as select rownum as id,rownum+1 as id2 from dual connect by level<=50000;

Table created.

SQL> create table t6 as select rownum as id,rownum+1 as id2 from dual connect by level<=500000;

Table created.

SQL>

② 分别对ID列建索引

继续完成建索引的准备工作

SQL> 
SQL> create index idx_id_t1 on t1(id);

Index created.

SQL> create index idx_id_t2 on t2(id);

Index created.

SQL> create index idx_id_t3 on t3(id);

Index created.

SQL> create index idx_id_t4 on t4(id);

Index created.

SQL> create index idx_id_t5 on t5(id);

Index created.

SQL> create index idx_id_t6 on t6(id);

Index created.

SQL> 

观察比较各个索引的大小

SQL> column segment_name format a20
SQL> select segment_name,bytes/1024
  2    from user_segments
  3  where segment_name in ('IDX_ID_T1','IDX_ID_T2','IDX_ID_T3','IDX_ID_T4','IDX_ID_T5','IDX_ID_T6');

SEGMENT_NAME         BYTES/1024
-------------------- ----------
IDX_ID_T1                    64
IDX_ID_T2                    64
IDX_ID_T3                    64
IDX_ID_T4                   128
IDX_ID_T5                  1024
IDX_ID_T6                  9216

6 rows selected.

SQL>

 但是在统计索引高度时,我们观察发现这些索引的高度相差无几,记录数最小是5条,最大是50万条,而高度最小的是BLEVEL=0,表示1层,高度最大的是BLEVEL=2,表示3层,也就差了2层而已!

观察比较各个索引的高度

SQL> column index_name format a20
SQL> select index_name,
  2         blevel,
  3         leaf_blocks,
  4         num_rows,
  5         distinct_keys,
  6         clustering_factor
  7    from user_ind_statistics
  8  where table_name in ('T1','T2','T3','T4','T5','T6')
  9  order by index_name;

INDEX_NAME               BLEVEL LEAF_BLOCKS   NUM_ROWS DISTINCT_KEYS CLUSTERING_FACTOR
-------------------- ---------- ----------- ---------- ------------- -----------------
IDX_ID_T1                     0           1          5             5                 1
IDX_ID_T2                     0           1         50            50                 1
IDX_ID_T3                     1           2        500           500                 1
IDX_ID_T4                     1          11       5000          5000                 9
IDX_ID_T5                     1         110      50000         50000               101
IDX_ID_T6                     2        1113     500000        500000              1035

6 rows selected.

SQL> 

注意一下:其中BLEVEL表示高度,0表示第一个块还没被索引装满,没产生管理的索引块,这个0可以理解为高度是1层,1则表示高度为2层,以此类推。

上面下面,为什么IDX_ID_T1、IDX_ID_T2、IDX_ID_T3三个索引一样大啊,都是64KB,它们的表记录可是5、50和500啊?

数据库的最小单位虽然是块,但是最小的空间分配单位却是区,要存在一个段至少需要一个区,你说的三个索引,就是三个索引段。

比如一个区含有8个块,一个块有8KB,段的最小空间就是64KB了,这是预分配的空间,即便是建一张空表,大小也是64KB。在空表上建一个索引,这个索引大小还是64KB,表和索引的实际大小只要不超过64KB,数据库查询都是64KB这么大,因为一次性已经分配给你一个区的大小了。但是一旦超过64KB,即便超过一点点,分配到的空间可能马上就是128KB这么大了。

2.4.2 妙用索引高度较低的特性

我们建了6张表,其中t5表有5万条记录,而t6表有50万条记录。大家说说这两条查询语句 select * from t5 where id=10 和select *from t6 where id=10,它们都是返回一条记录,但是t6表的记录数是t5表的10倍,它们的查询速度会不会差别很大?

观察上述与t5、t6 表相关的索引扫描的性能

SQL> 
SQL> show user;
USER is "MAXWELLPAN"
SQL> set autotrace traceonly
SQL> set linesize 1000
SQL> set timing on
SQL> select * from t5 where id=10;

Elapsed: 00:00:00.12

Execution Plan
----------------------------------------------------------
Plan hash value: 2977381114

-------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |           |     1 |    10 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T5        |     1 |    10 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_ID_T5 |     1 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"=10)


Statistics
----------------------------------------------------------
        395  recursive calls
          6  db block gets
        462  consistent gets
          1  physical reads
       1064  redo size
        624  bytes sent via SQL*Net to client
        390  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         43  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> 
SQL> 
SQL> 
SQL> select * from t6 where id=10;

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 661597417

-------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |           |     1 |    10 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T6        |     1 |    10 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_ID_T6 |     1 |       |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"=10)


Statistics
----------------------------------------------------------
        341  recursive calls
          6  db block gets
        380  consistent gets
          3  physical reads
        964  redo size
        624  bytes sent via SQL*Net to client
        390  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         40  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

这两个试验表明虽然一张表是5万条记录,另一张表是50万条记录,但是利用索引来返回同样记录数的查询,效率居然差不多?

主要是BLEVEL有关,产生的IO次数有点差别。速度相对也会有差别。

再次测试与t5、t6表相关的全表扫描查询的性能

SQL> 
SQL> drop index IDX_ID_T5;

Index dropped.

Elapsed: 00:00:00.25
SQL> select * from t5 where id=10;

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 2002323537

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    10 |    32   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T5   |     1 |    10 |    32   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("ID"=10)


Statistics
----------------------------------------------------------
         30  recursive calls
          0  db block gets
        155  consistent gets
          0  physical reads
          0  redo size
        620  bytes sent via SQL*Net to client
        390  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          5  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> drop index IDX_ID_T6;

Index dropped.

Elapsed: 00:00:00.13
SQL> select * from t6 where id=10;

Elapsed: 00:00:00.04

Execution Plan
----------------------------------------------------------
Plan hash value: 1930642322

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    10 |   293   (2)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T6   |     1 |    10 |   293   (2)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("ID"=10)


Statistics
----------------------------------------------------------
        101  recursive calls
          0  db block gets
       1090  consistent gets
       1034  physical reads
          0  redo size
        620  bytes sent via SQL*Net to client
        390  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          5  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> 

可以看出,由于删除了索引,针对t5、t6表的查询逻辑读差异明显。说明性能也是非常明显的。

由此得出结论,索引的这个高度不高的特性给查询带来了巨大的便利,但是请注意,我们的查询只返回1条记录。如果查询返回绝大部分的数据,那用索引反而要慢得多。

2.4.3 分区索引设计误区

分区表的索引分为两种,一种是局部索引,一种是全局索引。局部索引等同于为每个分区段建分区的索引,从user_segment 的数据字典中,我们可以观察到表有多少个分区,就有多少个分区索引的段。

先建分区表part_tab,插入数据,并分别在col2上建局部索引,在col3上建全局索引。

分区索引相关试验的准备工作

SQL> 
SQL> show user;
USER is "MAXWELLPAN"
SQL> drop table part_tab_purge;
drop table part_tab_purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


Elapsed: 00:00:00.10
SQL>

SQL> 
SQL> create table part_tab(id int,col2 int,col3 int)
  2            partition by range(id)
  3    (
  4    partition p1 values less than (10000),
  5    partition p2 values less than (20000),
  6    partition p3 values less than (30000),
  7    partition p4 values less than (40000),
  8    partition p5 values less than (50000),
  9    partition p6 values less than (60000),
 10    partition p7 values less than (70000),
 11    partition p8 values less than (80000),
 12    partition p9 values less than (90000),
 13    partition p10 values less than (100000),
 14    partition p11 values less than(maxvalue)
 15    )
 16    ;

Table created.

Elapsed: 00:00:00.05
SQL>

SQL> insert into part_tab select rownum,rownum+1,rownum+2 from dual connect by rownum <= 110000;

110000 rows created.

Elapsed: 00:00:00.14
SQL> commit;

Commit complete.

Elapsed: 00:00:00.00
SQL>
SQL> create index idx_par_tab_col2 on part_tab(col2) local;

Index created.

Elapsed: 00:00:00.15
SQL> create index idx_par_tab_col3 on part_tab(col3);

Index created.

Elapsed: 00:00:00.09
SQL>

分区索引情况查看
 

SQL> col segment_name format a20
SQL> col partition_name format a20
SQL> col segment_type format a20
SQL> select segment_name,partition_name,segment_type
  2    from user_segments
  3  where segment_name = 'PART_TAB';

SEGMENT_NAME         PARTITION_NAME       SEGMENT_TYPE
-------------------- -------------------- --------------------
PART_TAB             P1                   TABLE PARTITION
PART_TAB             P10                  TABLE PARTITION
PART_TAB             P11                  TABLE PARTITION
PART_TAB             P2                   TABLE PARTITION
PART_TAB             P3                   TABLE PARTITION
PART_TAB             P4                   TABLE PARTITION
PART_TAB             P5                   TABLE PARTITION
PART_TAB             P6                   TABLE PARTITION
PART_TAB             P7                   TABLE PARTITION
PART_TAB             P8                   TABLE PARTITION
PART_TAB             P9                   TABLE PARTITION

11 rows selected.

Elapsed: 00:00:00.06
SQL> 
SQL> 
SQL> select segment_name,partition_name,segment_type
  2    from user_segments
  3  where segment_name = 'IDX_PAR_TAB_COL2';

SEGMENT_NAME         PARTITION_NAME       SEGMENT_TYPE
-------------------- -------------------- --------------------
IDX_PAR_TAB_COL2     P1                   INDEX PARTITION
IDX_PAR_TAB_COL2     P10                  INDEX PARTITION
IDX_PAR_TAB_COL2     P11                  INDEX PARTITION
IDX_PAR_TAB_COL2     P2                   INDEX PARTITION
IDX_PAR_TAB_COL2     P3                   INDEX PARTITION
IDX_PAR_TAB_COL2     P4                   INDEX PARTITION
IDX_PAR_TAB_COL2     P5                   INDEX PARTITION
IDX_PAR_TAB_COL2     P6                   INDEX PARTITION
IDX_PAR_TAB_COL2     P7                   INDEX PARTITION
IDX_PAR_TAB_COL2     P8                   INDEX PARTITION
IDX_PAR_TAB_COL2     P9                   INDEX PARTITION

11 rows selected.

Elapsed: 00:00:00.09
SQL> 
SQL> select segment_name,partition_name,segment_type
  2    from user_segments
  3  where segment_name = 'IDX_PAR_TAB_COL3';

SEGMENT_NAME         PARTITION_NAME       SEGMENT_TYPE
-------------------- -------------------- --------------------
IDX_PAR_TAB_COL3                          INDEX

Elapsed: 00:00:00.03
SQL> 

建一张普通表norm_tab,字段和记录数与part_tab一样,并且同样在col2和col3上分别建索引.

继续做准备工作,构建普通表及索引

SQL> 
SQL> drop table norm_tab purge;
drop table norm_tab purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


Elapsed: 00:00:00.08
SQL> create table norm_tab(id int,col2 int,col3 int);

Table created.

Elapsed: 00:00:00.03
SQL> insert into norm_tab select rownum,rownum+1,rownum+2 from dual connect by rownum <= 110000;

110000 rows created.

Elapsed: 00:00:00.16
SQL> commit;

Commit complete.

Elapsed: 00:00:00.00
SQL> create index idx_nor_tab_col2 on norm_tab(col2);

Index created.

Elapsed: 00:00:00.11
SQL> create index idx_nor_tab_col3 on norm_tab(col3);

Index created.

Elapsed: 00:00:00.07
SQL>

我们来看看分别针对part_tab和norm_tab两表的col2列的查询效率如何,语句分别是select* from part_tab where col2=8;和select * from norm_tab where col2=8;,依然采用set autotrace 的跟踪方式。先查看针对part_tab的查询结果,发现索引扫描遍历了全部11个分区,在执行计划中我们可以观察到,Pstart和Pstop是从1到11。

全分区索引扫描产生大量逻辑读

SQL> 
SQL> set autotrace traceonly
SQL> set linesize 1000
SQL> set timing on
SQL> select * from part_tab where col2=8;

Elapsed: 00:00:00.05

Execution Plan
----------------------------------------------------------
Plan hash value: 3980401122

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name             | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |                  |     1 |    39 |    11   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE ALL                       |                  |     1 |    39 |    11   (0)| 00:00:01 |     1 |    11 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| PART_TAB         |     1 |    39 |    11   (0)| 00:00:01 |     1 |    11 |
|*  3 |    INDEX RANGE SCAN                        | IDX_PAR_TAB_COL2 |     1 |       |    11   (0)| 00:00:01 |     1 |    11 |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("COL2"=8)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


Statistics
----------------------------------------------------------
        972  recursive calls
          6  db block gets
       1464  consistent gets
         11  physical reads
       1020  redo size
        698  bytes sent via SQL*Net to client
        618  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
        102  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> 

普通表索引扫描逻辑读少得多

SQL> 
SQL> select * from norm_tab where col2=8;

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 2321776653

--------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                  |     1 |    39 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| NORM_TAB         |     1 |    39 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_NOR_TAB_COL2 |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("COL2"=8)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


Statistics
----------------------------------------------------------
         57  recursive calls
          6  db block gets
        164  consistent gets
          2  physical reads
       1008  redo size
        702  bytes sent via SQL*Net to client
        397  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> 

分别观察分区表和普通表的索引高度

SQL> 
SQL> set autotrace off
SQL> 
SQL> select index_name,
  2         blevel,
  3         leaf_blocks,
  4         num_rows,
  5         distinct_keys,
  6         clustering_factor
  7    from user_ind_partitions
  8  where index_name='IDX_PAR_TAB_COL2';

INDEX_NAME               BLEVEL LEAF_BLOCKS   NUM_ROWS DISTINCT_KEYS CLUSTERING_FACTOR
-------------------- ---------- ----------- ---------- ------------- -----------------
IDX_PAR_TAB_COL2              1          21       9999          9999                24
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10001         10001                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28
IDX_PAR_TAB_COL2              1          23      10000         10000                28

11 rows selected.

Elapsed: 00:00:00.10
SQL> select index_name,
  2         blevel,
  3         leaf_blocks,
  4         num_rows,
  5         distinct_keys,
  6         clustering_factor
  7    from user_ind_statistics
  8  where index_name='IDX_NOR_TAB_COL2';

INDEX_NAME               BLEVEL LEAF_BLOCKS   NUM_ROWS DISTINCT_KEYS CLUSTERING_FACTOR
-------------------- ---------- ----------- ---------- ------------- -----------------
IDX_NOR_TAB_COL2              1         244     110000        110000               299

Elapsed: 00:00:00.21
SQL>

分区索引扫描仅落在某一分区,性能大幅提升

SQL> 
SQL> set autotrace traceonly
SQL> select * from part_tab where col2=8 and id=7;

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 2640417554

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name             | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |                  |     1 |    39 |     4   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE SINGLE                    |                  |     1 |    39 |     4   (0)| 00:00:01 |     1 |     1 |
|*  2 |   TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| PART_TAB         |     1 |    39 |     4   (0)| 00:00:01 |     1 |     1 |
|*  3 |    INDEX RANGE SCAN                        | IDX_PAR_TAB_COL2 |    11 |       |     3   (0)| 00:00:01 |     1 |     1 |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("ID"=7)
   3 - access("COL2"=8)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        698  bytes sent via SQL*Net to client
        406  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

5.2.6 巧用三特征之存储列值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring gateway websocket自定义负载均衡

业务需求 公司IM服务主要基于netty实现websocket&#xff0c;为保证在线用户channel通道畅通故一直使用单机运行。现由于公司业务增加需要增加IM集群&#xff0c;由于channel通道不能缓存&#xff0c;故急需一套可以完整兼容之前功能的方案。 技术选型 1、采用spring websocke…

Bonree ONE荣获信通院“2022IT新治理年度明星产品”

今日&#xff0c;由信通院主办的“GOLFIT新治理领导力论坛”正式召开&#xff0c;论坛上公布了2022IT新治理年度评选活动的结果&#xff0c;博睿数据一体化智能可观测平台Bonree ONE凭借卓越的产品力以及优秀的用户体验&#xff0c;从一众产品中脱颖而出&#xff0c;获得“2022…

spring 事务@Transantional 失效及解决方案和总结

1、线程中方法&#xff0c;事务会失效 2、线程中方法&#xff0c;事务会失效。即使在线程方法上增加Transactional注解 3、事务正常回滚&#xff0c;A方法调用B的普通方法 4、事务正常回滚。A方法调用B的private普通方法 6、会抛出NullPointerException异常。 Methods ann…

rock3a: 基于自建数据集+yolov5s模型的rknn模型训练部署全流程

上一篇文章其实已经详述了模型训练到部署的整个流程&#xff0c;但是数据集到模型都是用的官方的coco数据集&#xff0c;这里为了记录开发板的模型训练到部署的整个流程&#xff0c;重新开了一篇文章进行记录。 首先准备数据集和rockchip官方推荐的yolov5源代码 这里需要注意的…

基于Node.js Vue企业产品展示网站

摘 要随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&am…

CAN201-Computer Network(2)

文章目录4. Network Layer4.1 Router4.1.1 Input port functions4.1.2 Destination-based forwarding4.1.3 Switching fabrics4.1.4 Input port queueing4.1.5 Output ports4.2 Internet Protocol4.2.1 IP fragmentation, reassembly4.3 IPv4 addressing4.3.1 Subnets4.3.2 Net…

高等数学(第七版)同济大学 习题11-4 个人解答

高等数学&#xff08;第七版&#xff09;同济大学 习题11-4 函数作图软件&#xff1a;Mathematica 1.设有一分布着质量的曲面Σ&#xff0c;在点(x,y,z)处它的面密度为μ(x,y,z)&#xff0c;用对面积的曲面积分表示这曲面对于x轴的转动惯量.\begin{aligned}&1. \ 设有一分…

IB生物课程介绍与Topic 1: Cell Biology考点分享

准备让孩子就读国际学校或者孩子正在国际学校就读的家长肯定听说过“IB”或者“IB班”&#xff0c;那IB究竟是什么呢&#xff1f;IB与IB课程 IB是International Baccalaureate&#xff08;国际文凭&#xff09;的简称&#xff0c;其课程体系国际文凭大学预科课程&#xff08;In…

Educational Codeforces Round 141 (Rated for Div. 2)A——C

ps&#xff1a;先自我检讨...自从世界杯开始后&#xff0c;就一直摆烂到现在。直到打了今年的第一场cf&#xff0c;看见打的这么菜&#xff0c;真是想remake/。后面我会陆陆续续的补完前段时间没有打的比赛... Dashboard - Educational Codeforces Round 141 (Rated for Div. …

ReentrantLock

目录 ReentrantLock ReentrantLock语法 ReentrantLock可重入 ReentrantLock可打断 ReentrantLock锁超时 ReentrantLock解决哲学家就餐问题 ReentrantLock公平锁 ReentrantLock条件变量 ReentrantLock ReentrantLock 相比于synchronized的特点 : 可中断:比如A线程拥有…

基于移动最小二乘法的曲线曲面拟合论文阅读笔记

基于移动最小二乘法的曲线曲面拟合论文阅读笔记 论文地址:http://www.cnki.com.cn/Article/CJFDTotal-GCTX200401016.htm 一、Problem Statement 传统的曲线(曲面)拟合方法一般使用最小二乘法&#xff0c; 通过使误差的平方和最小&#xff0c; 得到一个线性方程组&#xff0…

通过alist挂在阿里网盘的方法

1、在github官网https://github.com/alist-org/alist/releases/download/v3.8.0/alist-windows-amd64.zip下载alist软件客户端&#xff0c;双击运行&#xff0c;可以看到默认的密码和服务器地址&#xff0c;打开网页http://localhost:5244/manage/accounts&#xff0c;填写密码…

【Linux】Linux工具

文章目录软件包管理器yumVIM编辑器Linux编译器-gcc/g使用gcc如何完成预处理(进行宏替换)编译(生成汇编)汇编(生成机器课识别代码)链接在这里涉及到一个重要的概念: 函数库函数库一般分为静态库和动态库两种gcc选项gcc选项记忆Linux项目自动化构建工具-make/Makefile背景理解实例…

解决vue中报错 Duplicate keys detected:‘1‘. This may cause an update error.

报错截图&#xff1a; 报错原因&#xff1a; 通过上图的报错信息我们不难看出&#xff0c;报错的主要原因出现在 key 值上&#xff0c;报错的意思大概是检测到重复的 key 值&#xff0c;通俗来讲就是你的 key 值不是唯一的。 解决方案&#xff1a; 问题的根源找到了&#xff…

【初阶数据结构】——链表常见面试题剖析

文章目录前言题目1&#xff1a;移除链表元素题目分析思路1&#xff1a;暴力求解思路2&#xff1a;取非val值尾插至新链表思路讲解思考代码实现不带哨兵位带哨兵位题目2&#xff1a;合并两个有序链表题目分析思路讲解代码实现不带哨兵位带哨兵位题目3&#xff1a;反转链表题目分…

用ode45解微分方程遇到的实际问题

最近在用ode45解微分方程数值解&#xff0c;试图复现论文中的图。一般来说说微分方程&#xff08;组&#xff09;只要按照响应的条件去撰写好对应的回调函数即可&#xff0c;基本没什么难度&#xff0c;但对于本文遇到的的这个问题&#xff0c;可能还需要一些技巧去实现解法&am…

动态路由和导航守卫

一、动态路由1、什么是动态路由&#xff1f;将URL地址中可变的内容设置成参数&#xff0c;根据不同的参数渲染不同的组件。&#xff08;组件可以复用&#xff09;2、动态路由如何进行参数的传递&#xff1a;&#xff08;1&#xff09;如何设置URL地址中的参数&#xff1a;’/ur…

【手写 Vue2.x 源码】第十二篇 - 生成 ast 语法树-流程说明

一&#xff0c;前言 上篇&#xff0c;主要介绍了 vue 数据渲染核心流程&#xff0c;涉及以下几个点&#xff1a; 初次渲染时 template 模板被编译为 ast 语法树&#xff1b;通过 ast 语法树生成 render 函数&#xff1b;通过 render 函数返回 vnode 虚拟节点&#xff1b;使用…

基于K8s的DevOps平台实践(三)

文章目录前言1. Jenkins与k8s集成&#x1f351; 插件安装及配置&#x1f351; 演示动态slave pod&#x1f351; Pod-Template中容器镜像的制作&#x1f351; 实践通过Jenkinsfile实现demo项目自动发布到kubenetes环境2. Jenkins集成Sonarqube&#x1f351; sonarqube架构简介&a…

初阶产品经理必看:如何快速进阶B端产品经理

​从去年开始&#xff0c;大批的互联网企业开始转战B端&#xff0c;众多传统企业也早在几年前就开始向互联网转型。 产业互联网的兴起&#xff0c;让一个岗位的潜藏价值正在逐渐爆发&#xff0c;尤其是富有经验的背景&#xff0c;更加让身价越来越高。 这个岗位就是&#xff…