2 (a int,b int,c in,江蘇會(huì)計(jì)證考試報(bào)名,2022年會(huì)計(jì)從業(yè)資格考試報(bào)名,2022年江蘇會(huì)計(jì)從業(yè)證報(bào)名,2022年江蘇會(huì)計(jì)從業(yè)考試報(bào)名,江蘇2022年會(huì)計(jì)從業(yè)資格考試成報(bào)名,2022年江蘇會(huì)計(jì)從業(yè)考試,會(huì)計(jì)電算化考試試題,2022年江蘇會(huì)計(jì)電算化,江蘇會(huì)計(jì)電算化試題,江蘇會(huì)計(jì)電算化考試,江蘇初級(jí)會(huì)計(jì)電算化,江蘇初級(jí)會(huì)計(jì)電算化考試">

射精一区欧美专区|国产精品66xx|亚洲视频一区导航|日韩欧美人妻精品中文|超碰婷婷xxnx|日韩无码综合激情|特级黄片一区二区|四虎日韩成人A√|久久精品内谢片|亚洲成a人无码电影

您現(xiàn)在的位置:首頁(yè) > IT認(rèn)證 > oracle認(rèn)證 >

Oracle中如何避免使用特定錯(cuò)誤索引


有的時(shí)候,使用錯(cuò)誤的索引會(huì)導(dǎo)致Oracle數(shù)據(jù)庫(kù)的效率明顯下降,通過(guò)一些方法或者是技巧可以有效的避免這個(gè)問(wèn)題:

  這個(gè)例子中,如果我想使用idx_a而不是idx_b.

   SQL> create table test
  2 (a int,b int,c int,d int);
  Table created.
  SQL> begin
  2 for i in 1..50000
  3 loop
  4 insert into mytest values(i,i,i,i);
  5 end loop;
  6 commit;
  7 end;
  8 /
  PL/SQL procedure successfully completed.
  SQL> create index idx_a on mytest(a,b,c);
  Index created.
  SQL> create index idx_b on mytest(b);
  Index created.

  如表mytest,有字段a,b,c,d,在a,b,c上建立聯(lián)合索引idx_a(a,b,c),在b上單獨(dú)建立了一個(gè)索引idx_b(b)。

  在正常情況下,where a=? and b=? and c=?會(huì)用到索引idx_a,where b=?會(huì)用到索引idx_b

  比如:

   SQL> analyze table mytest compute statistics;
  Table analyzed.
  SQL> select num_Rows from user_tables where table_name='MYTEST';
  NUM_ROWS
  ----------
  50000
  SQL> select distinct_keys from user_indexes where index_name='IDX_A';
  DISTINCT_KEYS
  -------------
  50000
  SQL> set autotrace traceonly
  SQL> select d from mytest
  2 where a=10 and b=10 and c=10;
  Execution Plan
  ----------------------------------------------------------
  Plan hash value: 1542625214
  --------------------------------------------------------------------------------
  ------
  | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
  |
  --------------------------------------------------------------------------------
  ------
  | 0 | SELECT STATEMENT | | 1 | 16 | 2 (0)| 00:0
  0:01 |
  | 1 | TABLE ACCESS BY INDEX ROWID| MYTEST | 1 | 16 | 2 (0)| 00:0
  0:01 |
  |* 2 | INDEX RANGE SCAN | IDX_A | 1 | | 1 (0)| 00:0
  0:01 |
  --------------------------------------------------------------------------------
  ------
  Predicate Information (identified by operation id):
  ---------------------------------------------------
  2 - access("A"=10 AND "B"=10 AND "C"=10)
  Statistics
  ----------------------------------------------------------
  1 recursive calls
  0 db block gets
  4 consistent gets
  0 physical reads
  0 redo size
  508 bytes sent via SQL*Net to client
  492 bytes received via SQL*Net from client
  2 SQL*Net roundtrips to/from client
  0 sorts (memory)
  0 sorts (disk)
  1 rows processed
  SQL> select d from mytest
  2 where b=500;
  Execution Plan
  ----------------------------------------------------------
  Plan hash value: 530004086
  --------------------------------------------------------------------------------
  ------
  | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
  |
  --------------------------------------------------------------------------------
  ------
  | 0 | SELECT STATEMENT | | 1 | 8 | 2 (0)| 00:0
  0:01 |
  | 1 | TABLE ACCESS BY INDEX ROWID| MYTEST | 1 | 8 | 2 (0)| 00:0
  0:01 |
  |* 2 | INDEX RANGE SCAN | IDX_B | 1 | | 1 (0)| 00:0
  0:01 |
  --------------------------------------------------------------------------------
  ------
  Predicate Information (identified by operation id):
  ---------------------------------------------------
  2 - access("B"=500)
  Statistics
  ----------------------------------------------------------
  1 recursive calls
  0 db block gets
  4 consistent gets
  0 physical reads
  0 redo size
  508 bytes sent via SQL*Net to client
  492 bytes received via SQL*Net from client
  2 SQL*Net roundtrips to/from client
  0 sorts (memory)
  0 sorts (disk)
  1 rows processed

但是在這樣一個(gè)條件下:where a=? and b=? and c=? group by b會(huì)用到哪個(gè)索引呢?在索引的分析數(shù)據(jù)不正確(很長(zhǎng)時(shí)間沒(méi)有分析)或根本沒(méi)有分析數(shù)據(jù)的情況下,oracle往往會(huì)使用索引idx_b。通過(guò)執(zhí)行計(jì)劃的分析,這個(gè)索引的使用,將大大耗費(fèi)查詢時(shí)間。

  比如在索引有統(tǒng)計(jì)信息,分析數(shù)據(jù)正確的情況下:

  SQL> select max(d) from mytest
  2 where a=50 and b=50 and c=50
  3 group by b;
  Execution Plan
  ----------------------------------------------------------
  Plan hash value: 422688974
  --------------------------------------------------------------------------------
  -------
  | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
  e |
  --------------------------------------------------------------------------------
  -------
  | 0 | SELECT STATEMENT | | 1 | 16 | 2 (0)| 00:
  00:01 |
  | 1 | SORT GROUP BY NOSORT | | 1 | 16 | 2 (0)| 00:
  00:01 |
  | 2 | TABLE ACCESS BY INDEX ROWID| MYTEST | 1 | 16 | 2 (0)| 00:
  00:01 |
  |* 3 | INDEX RANGE SCAN | IDX_A | 1 | | 1 (0)| 00:
  00:01 |
  --------------------------------------------------------------------------------
  -------
  Predicate Information (identified by operation id):
  ---------------------------------------------------
  3 - access("A"=50 AND "B"=50 AND "C"=50)
  Statistics
  ----------------------------------------------------------
  1 recursive calls
  0 db block gets
  3 consistent gets
  0 physical reads
  0 redo size
  513 bytes sent via SQL*Net to client
  492 bytes received via SQL*Net from client
  2 SQL*Net roundtrips to/from client
  0 sorts (memory)
  0 sorts (disk)
  1 rows processed
  但如果索引分析數(shù)據(jù)不正確:
  SQL> select num_rows from user_tables
  2 where table_name='MYTEST';
  NUM_ROWS
  ----------
  50000
  SQL> analyze index idx_a delete statistics;
  Index analyzed.
  SQL> analyze index idx_b delete statistics;
  Index analyzed.
  SQL> select distinct_keys from user_indexes
  2 where index_name in ('IDX_A','IDX_B');
  DISTINCT_KEYS
  -------------
  SQL> select max(d) from mytest where a=50 and b=50 and c=50 group by b;
  Execution Plan
  ----------------------------------------------------------
  Plan hash value: 3925507835
  --------------------------------------------------------------------------------
  -------
  | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
  e |
  --------------------------------------------------------------------------------
  -------
  | 0 | SELECT STATEMENT | | 1 | 16 | 2 (0)| 00:
  00:01 |
  | 1 | SORT GROUP BY NOSORT | | 1 | 16 | 2 (0)| 00:
  00:01 |
  |* 2 | TABLE ACCESS BY INDEX ROWID| MYTEST | 1 | 16 | 2 (0)| 00:
  00:01 |
  |* 3 | INDEX RANGE SCAN | IDX_B | 1 | | 1 (0)| 00:
  00:01 |
  --------------------------------------------------------------------------------
  -------
  Predicate Information (identified by operation id):
  ---------------------------------------------------
  2 - filter("A"=50 AND "C"=50)
  3 - access("B"=50)
  Statistics
  ----------------------------------------------------------
  0 recursive calls
  0 db block gets
  3 consistent gets
  0 physical reads
  0 redo size
  513 bytes sent via SQL*Net to client
  492 bytes received via SQL*Net from client
  2 SQL*Net roundtrips to/from client
  0 sorts (memory)
  0 sorts (disk)
  1 rows processed

  我們可以通過(guò)如下的技巧避免使用idx_b,而使用idx_a。

      where a=? and b=? and c=? group by b||'' --如果b是字符類型
  where a=? and b=? and c=? group by b+0 --如果b是數(shù)字類型

  通過(guò)這樣簡(jiǎn)單的改變,往往可以是查詢時(shí)間提交很多倍

  當(dāng)然,我們也可以使用no_index提示,相信很多人沒(méi)有用過(guò),也是一個(gè)不錯(cuò)的方法

    SQL> select /*+ no_index(mytest,idx_b) */ max(d) from mytest where a=50 and b=50 and c=50 group by b;
  Execution Plan
  ----------------------------------------------------------
  Plan hash value: 422688974
  --------------------------------------------------------------------------------
  -------
  | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Tim
  e |
  --------------------------------------------------------------------------------
  -------
  | 0 | SELECT STATEMENT | | 1 | 16 | 9 (0)| 00:
  00:01 |
  | 1 | SORT GROUP BY NOSORT | | 1 | 16 | 9 (0)| 00:
  00:01 |
  | 2 | TABLE ACCESS BY INDEX ROWID| MYTEST | 1 | 16 | 9 (0)| 00:
  00:01 |
  |* 3 | INDEX RANGE SCAN | IDX_A | 500 | | 1 (0)| 00:
  00:01 |
  --------------------------------------------------------------------------------
  -------
  Predicate Information (identified by operation id):
  ---------------------------------------------------
  3 - access("A"=50 AND "B"=50 AND "C"=50)
  Statistics
  ----------------------------------------------------------
  1 recursive calls
  0 db block gets
  3 consistent gets
  0 physical reads
  0 redo size
  513 bytes sent via SQL*Net to client
  492 bytes received via SQL*Net from client
  2 SQL*Net roundtrips to/from client
  0 sorts (memory)
  0 sorts (disk)
  1 rows processed

相關(guān)文章

無(wú)相關(guān)信息
更新時(shí)間2022-03-13 11:05:03【至頂部↑】
聯(lián)系我們 | 郵件: | 客服熱線電話:4008816886(QQ同號(hào)) | 

付款方式留言簿投訴中心網(wǎng)站糾錯(cuò)二維碼手機(jī)版

客服電話: