Oracle:具有哈希集群的多块读取对象

时间:2019-07-16 03:37:17

标签: sql oracle performance database-administration

使用散列集群后,我的查询运行得慢得多(数据库时间的6.82%到76%)。而且AWR报告说,无锁->多块读取对象是关键。

查询是

SELECT count(1) INTO result FROM (
    SELECT s_w_id, s_i_id, s_quantity
        FROM bmsql_stock
        WHERE s_w_id = in_w_id AND s_quantity < in_threshold AND s_i_id IN (
            SELECT ol_i_id
                FROM bmsql_district
                JOIN bmsql_order_line ON ol_w_id = d_w_id
                AND ol_d_id = d_id
                AND ol_o_id >= d_next_o_id - 20
                AND ol_o_id < d_next_o_id
                WHERE d_w_id = in_w_id AND d_id = in_d_id
        )
);

表ddl是(请注意order_line表不是集群的)

create cluster bmsql_stock_cluster (
  s_w_id integer,
  s_i_id integer
)
single table
hashkeys 300000000
hash is ( (s_i_id-1) * 3000 + s_w_id-1 )
size 270
pctfree 0 initrans 2 maxtrans 2
storage (buffer_pool keep) parallel (degree 96);

create table bmsql_stock (
  s_w_id       integer       not null,
  s_i_id       integer       not null,
  s_quantity   integer,
  s_ytd        integer,
  s_order_cnt  integer,
  s_remote_cnt integer,
  s_data       varchar(50),
  s_dist_01    char(24),
  s_dist_02    char(24),
  s_dist_03    char(24),
  s_dist_04    char(24),
  s_dist_05    char(24),
  s_dist_06    char(24),
  s_dist_07    char(24),
  s_dist_08    char(24),
  s_dist_09    char(24),
  s_dist_10    char(24)
)
cluster bmsql_stock_cluster(
  s_w_id, s_i_id
);

create unique index bmsql_stock_pkey
  on bmsql_stock (s_i_id, s_w_id)
  parallel 32
  pctfree 1 initrans 3
  compute statistics;

create cluster bmsql_district_cluster (
  d_id integer,
  d_w_id integer
)
single table
hashkeys 30000
hash is ( (((d_w_id-1)*10)+d_id-1) )
size 3496
initrans 4
storage (buffer_pool default) parallel (degree 32);

create table bmsql_district (
  d_id         integer       not null,
  d_w_id       integer       not null,
  d_ytd        decimal(12,2),
  d_tax        decimal(4,4),
  d_next_o_id  integer,
  d_name       varchar(10),
  d_street_1   varchar(20),
  d_street_2   varchar(20),
  d_city       varchar(20),
  d_state      char(2),
  d_zip        char(9)
)
cluster bmsql_district_cluster(
  d_id, d_w_id
);

create unique index bmsql_district_pkey
  on bmsql_district (d_w_id, d_id)
  pctfree 5 initrans 3
  parallel 1
  compute statistics;

create table bmsql_order_line (
  ol_w_id         integer   not null,
  ol_d_id         integer   not null,
  ol_o_id         integer   sort,
  ol_number       integer   sort,
  ol_i_id         integer   not null,
  ol_delivery_d   timestamp,
  ol_amount       decimal(6,2),
  ol_supply_w_id  integer,
  ol_quantity     integer,
  ol_dist_info    char(24)
);

create unique index bmsql_order_line_pkey
  on bmsql_order_line (ol_w_id, ol_d_id, ol_o_id, ol_number)
  compute statistics;

最后,多块读取对象相关指标:

Latch Activity:
Latch Name  Get Requests    Pct Get Miss    Avg Slps /Miss  Wait Time (s)   NoWait Requests
// before
multiblock read objects 42,906  0.24    0.00    0   0   
// after
multiblock read objects 302,570,536 87.49   0.04    22385   0

Latch Sleep Breakdown:
Latch Name  Get Requests    Misses  Sleeps  Spin Gets
multiblock read objects 302,570,536 264,712,892 11,385,692  254,114,619

Latch Miss Source:
Latch Name  Where   NoWait Misses   Sleeps  Waiter Sleeps
multiblock read objects kcbzibmlt   0   5,886,699   5,927,472
multiblock read objects kcbzibmlt: normal mbr free  0   5,498,253   5,457,785   

以及具有统计信息的执行计划:

Plan hash value: 485221244

--------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                       |      1 |        |      1 |00:00:00.11 |    1472 |       |       |          |
|   1 |  SORT AGGREGATE                     |                       |      1 |      1 |      1 |00:00:00.11 |    1472 |       |       |          |
|   2 |   NESTED LOOPS                      |                       |      1 |        |      4 |00:00:00.11 |    1472 |       |       |          |
|   3 |    NESTED LOOPS                     |                       |      1 |    103 |    220 |00:00:00.10 |    1240 |       |       |          |
|   4 |     VIEW                            | VW_NSO_1              |      1 |    390 |    220 |00:00:00.10 |     578 |       |       |          |
|   5 |      HASH UNIQUE                    |                       |      1 |      1 |    220 |00:00:00.10 |     578 |  1397K|  1397K| 1342K (0)|
|   6 |       MERGE JOIN                    |                       |      1 |    390 |    221 |00:00:00.10 |     578 |       |       |          |
|*  7 |        TABLE ACCESS HASH            | BMSQL_DISTRICT        |      1 |     62 |      1 |00:00:00.01 |       1 |       |       |          |
|*  8 |        FILTER                       |                       |      1 |        |    221 |00:00:00.10 |     577 |       |       |          |
|*  9 |         FILTER                      |                       |      1 |        |    221 |00:00:00.10 |     577 |       |       |          |
|  10 |          TABLE ACCESS BY INDEX ROWID| BMSQL_ORDER_LINE      |      1 |   2500 |  31249 |00:00:00.02 |     577 |       |       |          |
|* 11 |           INDEX RANGE SCAN          | BMSQL_ORDER_LINE_PKEY |      1 |   2500 |  31249 |00:00:00.01 |     106 |       |       |          |
|* 12 |     INDEX UNIQUE SCAN               | BMSQL_STOCK_PKEY      |    220 |      1 |    220 |00:00:00.01 |     662 |       |       |          |
|* 13 |    TABLE ACCESS BY INDEX ROWID      | BMSQL_STOCK           |    220 |    103 |      4 |00:00:00.01 |     232 |       |       |          |
--------------------------------------------------------------------------------------------------------------------------------------------------

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

   7 - access("BMSQL_DISTRICT"."D_ID"=:SYS_B_5 AND "BMSQL_DISTRICT"."D_W_ID"=:SYS_B_4)
   8 - filter("OL_O_ID"<"D_NEXT_O_ID")
   9 - filter("OL_O_ID">="D_NEXT_O_ID"-:SYS_B_3)
  11 - access("OL_W_ID"=:SYS_B_4 AND "OL_D_ID"=:SYS_B_5)
  12 - access("S_I_ID"="OL_I_ID" AND "S_W_ID"=:SYS_B_1)
  13 - filter("S_QUANTITY"<:SYS_B_2)

Note
-----
   - dynamic sampling used for this statement (level=6)

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

多块读取与索引/表扫描有关,但是在我看来,更改后的表不需要完全扫描操作。希望有人能为我解释这个问题。预先感谢。

更新:取消对DISTRICT表的集群操作后,其运行速度很快

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2385307489

------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                       |      1 |        |      1 |00:00:00.01 |     802 |       |       |          |
|   1 |  SORT AGGREGATE                   |                       |      1 |      1 |      1 |00:00:00.01 |     802 |       |       |          |
|   2 |   NESTED LOOPS                    |                       |      1 |        |      9 |00:00:00.01 |     802 |       |       |          |
|   3 |    NESTED LOOPS                   |                       |      1 |    137 |    191 |00:00:00.02 |     605 |       |       |          |
|   4 |     VIEW                          | VW_NSO_1              |      1 |      6 |    191 |00:00:00.01 |      30 |       |       |          |
|   5 |      HASH UNIQUE                  |                       |      1 |      1 |    191 |00:00:00.01 |      30 |  1397K|  1397K| 1321K (0)|
|   6 |       NESTED LOOPS                |                       |      1 |      6 |    195 |00:00:00.02 |      30 |       |       |          |
|   7 |        TABLE ACCESS BY INDEX ROWID| BMSQL_DISTRICT        |      1 |      1 |      1 |00:00:00.01 |       3 |       |       |          |
|*  8 |         INDEX UNIQUE SCAN         | BMSQL_DISTRICT_PKEY   |      1 |      1 |      1 |00:00:00.01 |       2 |       |       |          |
|   9 |        TABLE ACCESS BY INDEX ROWID| BMSQL_ORDER_LINE      |      1 |      6 |    195 |00:00:00.02 |      27 |       |       |          |
|* 10 |         INDEX RANGE SCAN          | BMSQL_ORDER_LINE_PKEY |      1 |    383 |    195 |00:00:00.01 |       4 |       |       |          |
|* 11 |     INDEX UNIQUE SCAN             | BMSQL_STOCK_PKEY      |    191 |      1 |    191 |00:00:00.01 |     575 |       |       |          |
|* 12 |    TABLE ACCESS BY INDEX ROWID    | BMSQL_STOCK           |    191 |    137 |      9 |00:00:00.01 |     197 |       |       |          |
------------------------------------------------------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):

   8 - access("BMSQL_DISTRICT"."D_W_ID"=:SYS_B_4 AND "BMSQL_DISTRICT"."D_ID"=:SYS_B_5)
  10 - access("OL_W_ID"=:SYS_B_4 AND "OL_D_ID"=:SYS_B_5 AND "OL_O_ID">="D_NEXT_O_ID"-:SYS_B_3 AND "OL_O_ID"<"D_NEXT_O_ID")
  11 - access("S_I_ID"="OL_I_ID" AND "S_W_ID"=:SYS_B_1)
  12 - filter("S_QUANTITY"<:SYS_B_2)

Note
-----
   - dynamic sampling used for this statement (level=6)

43 rows selected.

0 个答案:

没有答案