日期:2014-05-17  浏览次数:21082 次

高手帮忙看一个表索引问题。用索引查询反而更慢了
-- Create table
create table Test
(
  UA NUMBER(20) not null,
  PPID NUMBER(8) not null,
  MSG_ID NUMBER(5) not null,
  PRIORITY NUMBER(2) default 64,
  LASTSEND_DATE DATE not null,
  MSG_DATA VARCHAR2(2048) not null,
  MSG_INLIST NUMBER(1) default 0,
  MODIFY_PRIORITY NUMBER(2) default 60 not null
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
  initial 64K
  minextents 1
  maxextents unlimited
  );

-- Create/Recreate primary, unique and foreign key constraints 
alter table Test
  add constraint Test_KEY primary key (UA, PPID, MSG_ID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
  initial 64K
  minextents 1
  maxextents unlimited
  );

-- Create/Recreate indexes 
create index Test_INDEX on Test (MODIFY_PRIORITY, LASTSEND_DATE)
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
  initial 64K
  minextents 1
  maxextents unlimited
  );
我用如下语句查询,select * from test where MSG_INLIST = 0 order by modify_priority,lastsend_date 1000万数据执行要1个小时,为什么呢,我是用索引排序的啊

------解决方案--------------------
MSG_INLIST = 0有多少数据量。
你建的索引,然后这个查询sql,可能连index skip scan都用不上。
------解决方案--------------------
引用楼主 lgand88 的帖子:
-- Create table
create table Test
(
UA NUMBER(20) not null,
PPID NUMBER(8) not null,
MSG_ID NUMBER(5) not null,
PRIORITY NUMBER(2) default 64,
LASTSEND_DATE DATE not null,
MSG_DATA VARCHAR2(2048) not null,
MSG_INLIST NUMBER(1) default 0,
MODIFY_PRIORITY NUMBER(2) default 60 not null
)
tablespace USERS


------解决方案--------------------
MSG_INLIST NUMBER(1) default 0, 
MODIFY_PRIORITY NUMBER(2) default 60 not null 

建立在这两个字段上的复合B树索引,对查询性能的提高没有什么作用.因为,这两个字段的选择性及数据分布性不高.


------解决方案--------------------
ORACLE方面针对优化的一些常识, 在COST模式下, 系统会根据情况,自动判断出比较优化的执行计划,并非建立索引就一定
会使用索引. 当然,在 ORACLE 9I之前, 默认的RULE模式下, 会使用索引的一些观念仍然在很多的地方流传,并影响很多人.

随着ORACLE版本的变化,原来的一些想法和认识已经片面和过时.这个贴子具有一定典型代表,值得推荐.