我这里有两张表: po_headers 和po_lines;
表结构如下:
create table po_headers(
ph_id number,
ph_segment varchar2(50)
primary key(ph_id)
)
/
create table po_lines(
pl_id number,
ph_id number,
pl_segment varchar2(50),
pl_name varchar2(60)
primary key(pl_id)
)
/
其中po_headers表中主键列是唯一索引;
po_lines表中除了主键外,还有一个唯一索引:
create unique index line_seg_index on ets_flex_values(ph_id,pl_segment);
这两张表中记录不是太多,其中po_lines表中大致有700条记录.
我的数据库是9i,
其中比较疑惑的是下面这条sql,po_headers走了索引,而对po_lines表的操作,没有走line_seg_index索引,而是走了全表扫描.
select ph.*,pl.* from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;
而下面的这条语句会走索引:
select ph.*,pl.ph_id,pl.pl_segment from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;
但如果在po_lines上创建下面的普通索引:
create index line_seg_index on ets_flex_values(ph_id);
则下面的sql会选择索引:
select ph.*,pl.* from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;
那位大侠能详细讲解一下oracle的索引原理?
表结构如下:
create table po_headers(
ph_id number,
ph_segment varchar2(50)
primary key(ph_id)
)
/
create table po_lines(
pl_id number,
ph_id number,
pl_segment varchar2(50),
pl_name varchar2(60)
primary key(pl_id)
)
/
其中po_headers表中主键列是唯一索引;
po_lines表中除了主键外,还有一个唯一索引:
create unique index line_seg_index on ets_flex_values(ph_id,pl_segment);
这两张表中记录不是太多,其中po_lines表中大致有700条记录.
我的数据库是9i,
其中比较疑惑的是下面这条sql,po_headers走了索引,而对po_lines表的操作,没有走line_seg_index索引,而是走了全表扫描.
select ph.*,pl.* from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;
而下面的这条语句会走索引:
select ph.*,pl.ph_id,pl.pl_segment from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;
但如果在po_lines上创建下面的普通索引:
create index line_seg_index on ets_flex_values(ph_id);
则下面的sql会选择索引:
select ph.*,pl.* from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;
那位大侠能详细讲解一下oracle的索引原理?
Oracle 9i & 10g编程艺术:深入数据库体系结构
里面讲解得非常详细
第一个语句未使用po_lines上的索引原因是,由于数据量较少,
全表扫描比使用索引和读取表数据块代价更低。2、第二句使用索引的原因是,从po_lines中查询出的列都
出现在索引中,所以,只需要扫描索引就可以了,不需要读取表
数据块。3、表连接执行计划主要有三种形式,NEST LOOP、HASH JOIN、
MERGE JOIN具体使用那种,要看统计数据和执行计划。4、索引原理可以读一下TOM的ORACLE 9I/10g编程艺术
这条语句:
select ph.*,pl.* from po_headers ph,po_lines pl
where ph.ph_id = pl.ph_id and ph.ph_id = 340;用不上索引,没有匹配的,即使是ets_flex_values(ph_id,pl_segment),使用索引的条件:
查询字段数等于或包含索引字段,根据唯一索引,b*树的建立规则,复合索引字段ph_id,pl_segment是作为一个整体作为树中的节点,而不是先ph_id,然后pl_segment在ph_id节点的子节点这种方式。而你单独查pl.ph_id是不匹配b*树查找方式的。所以不会利用到索引。另外即使符合使用索引的条件,优化也会自己分析,是不是全表扫描来得更快。也不一定会使用索引。