【问题标题】:Strange work of Oracle indexOracle索引的奇怪工作
【发布时间】:2018-03-28 08:27:11
【问题描述】:

我已将位图索引添加到现有表中

CREATE BITMAP INDEX idx_1 ON table1 (col1) COMPUTE STATISTICS;

但是当我解释查询计划时,新索引没有被优化器使用并且表被全扫描。

之后我创建了我的表的副本并创建了相同的索引,并且优化器使用了索引!

我在原始表和副本表上删除并重新创建了索引,但结果相同 - 原始表索引不起作用,而副本表索引正在工作。

当我尝试提示优化器在原始表上使用索引时,成本是全表扫描方法的 3 倍。

我正在使用 Oracle 11gr2。

    create table AP_IT.T_LEAD_MAIN3
(
  id                NUMBER not null,
  fill_date         DATE not null,
  source_code       NUMBER default 0 not null,
  product_code      NUMBER not null,
  phone             VARCHAR2(64) not null,
  amount            NUMBER,
  amount_scored     NUMBER,
  birthdate         DATE,
  children          NUMBER,
  city_name         VARCHAR2(200),
  city_type         VARCHAR2(4),
  convenient_time   VARCHAR2(400),
  email             VARCHAR2(200),
  firstname         VARCHAR2(200),
  homephone         VARCHAR2(64),
  id_type_form      VARCHAR2(120),
  iin               VARCHAR2(48),
  lastname          VARCHAR2(200),
  marriage          VARCHAR2(4),
  middlename        VARCHAR2(200),
  name              VARCHAR2(600),
  offer_type        VARCHAR2(80),
  order_number      VARCHAR2(120),
  pensioner         VARCHAR2(4),
  period            NUMBER default 0,
  period_scored     NUMBER,
  place_to_get_loan VARCHAR2(400),
  region            VARCHAR2(12),
  rnn               VARCHAR2(48),
  salary            NUMBER,
  score_date        DATE,
  scored            NUMBER default 0,
  sent_email        DATE,
  sent_sms          DATE,
  sex               VARCHAR2(4),
  udost             VARCHAR2(36),
  udost_enddate     DATE,
  work_date         DATE,
  id_old            NUMBER(32),
  transac_type      NUMBER,
  utm_test          NVARCHAR2(100),
  utm_content       NVARCHAR2(100),
  utm_medium        NVARCHAR2(100),
  utm_name          NVARCHAR2(100),
  utm_source        NVARCHAR2(100),
  utm_term          NVARCHAR2(100),
  order_id          NUMBER,
  mm                NUMBER,
  call_start_time   VARCHAR2(10),
  call_end_time     VARCHAR2(10),
  call_date         DATE
)
tablespace RISK_DATA
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 80K
    next 1M
    minextents 1
    maxextents unlimited
  );

-- Create/Recreate primary, unique and foreign key constraints 
alter table AP_IT.T_LEAD_MAIN3
  add constraint PK_LEAD_MAIN3 primary key (ID)
  using index 
  tablespace RISK_DATA
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 80K
    next 1M
    minextents 1
    maxextents unlimited
  );
alter table AP_IT.T_LEAD_MAIN3
  add foreign key (SOURCE_CODE)
  references AP_IT.T_LEAD_SOURCE (SOURCE_CODE);
alter table AP_IT.T_LEAD_MAIN3
  add foreign key (PRODUCT_CODE)
  references AP_IT.T_LEAD_PRODUCT (PRODUCT_CODE);

CREATE BITMAP INDEX idx_tblleadmain_3
ON AP_IT.T_LEAD_MAIN3 (SCORED) COMPUTE STATISTICS;

查询:

select "AMOUNT_SCORED","ORDER_NUMBER","SCORED" 
from ap_it.t_lead_main3 t 
where t.scored = 1

原表计划

--------------------------------------------------------------
| Id  | Operation         | Name        | Rows  | Cost (%CPU)|
--------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |   573K|  4284   (1)|
|*  1 |  TABLE ACCESS FULL| T_LEAD_MAIN |   573K|  4284   (1)|
--------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("T"."SCORED"=1)

复制表的计划

    --------------------------------------------------------------------------------
Plan hash value: 2628593030
-------------------------------------------------------------------------------
| Id  | Operation                    | Name              | Rows  | Cost (%CPU)|
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                   |   753K|  1637   (1)|
|   1 |  TABLE ACCESS BY INDEX ROWID | T_LEAD_MAIN3      |   753K|  1637   (1)|
|   2 |   BITMAP CONVERSION TO ROWIDS|                   |       |            |
|*  3 |    BITMAP INDEX SINGLE VALUE | IDX_TBLLEADMAIN_3 |       |            |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("T"."SCORED"=1)

【问题讨论】:

  • 表架构?查询文本?
  • 提问时请更具体一点:到目前为止,您对代码示例做了哪些尝试? (I downvoted because there is no code) / 您有什么期望? / 您会遇到什么错误? 请查看“How to ask”以获得帮助
  • select * from schema1.table1 t where t.col1 = 1
  • 为什么您在计划中省略了COSTE-RowsE-Bytes 列?它们对于理解 Oracle 为何选择一个计划而不是另一个计划至关重要?
  • 创建索引后是否在原表上运行dbms_stats.gather_table_stats()

标签: oracle database-indexes


【解决方案1】:

你已经回答了这个问题:

之后我创建了我的表的副本并创建了相同的索引...

创建一个表的副本(使用CTAS - create table .. as select ..)产生的不是原始表的完全相同的克隆,而是两个空间分配(例如,如果原始表在删除后包含大量可用空间)和顺序或行(例如使用order by 创建)可能会发生变化。

因此,对于原始表,CBOFULL TABLE SCAN 计算较低的成本,但对于新表(在您使用 CTAS重组之后)位图 indexx 访问是首选。

只有当您使用10053 trace 跟踪您的两个查询时才能获得全部真相,但通常您不应该期望相同(逻辑)数据的优化器行为相同。桌子的物理布局起着至关重要的作用

【讨论】:

  • 好的,我没有在 ctas 中使用 order by 子句,但我理解你的解释。还有一个问题,在表上收集统计数据对我有帮助吗?
  • 通过“帮助我”,我假设您想强制数据库使用索引,是的,这可能会起作用。但是,另一种解释是 Oracle 正在做正确的事情,并且完全扫描是比使用索引更快。
  • 为了好玩而试图收集复制表的统计信息,优化器也没有使用索引(
  • @akaipbay 好吧,是的,统计数据与 CBO 非常相关。检查dynamic sampling,这是缺少优化器统计信息时会发生的情况
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 2015-07-12
  • 2018-10-05
  • 2014-08-15
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多