请教一个关于索引的问题

[复制链接]
查看11 | 回复6 | 2011-12-29 15:35:34 | 显示全部楼层 |阅读模式
假如有张表:
create table test(transaction_id number,transaction_type_id number,transaction_type_name varchar2(20));
表里的内容都是类似
1,1,'一'
2,1,'一'
3,2,'二'
4,3,'三'
5,3,'三'
6,3,'三',
7,4,'四'
这样的数据(数据量很大),transaction_type_id其实和transaction_type_name代表的意思是一样的,transaction_type_id总共只有30种不同的值
那么假如在test表上有一个索引为:
create index test_n1 on test(transaction_type_id);
那查询数据时
select * from test where transaction_type_id=3 and transaction_type_name='三';
会不会比
select * from test where transaction_type_id=3;
速度要慢呢?
自己做了个测试,看起来两种查询方式也没什么差别(没建索引前和建了索引后也没什么差别)
请教各位在已经可以确定查询出来的数据时,假如再多加一个无关紧要的条件,会不会改变查询时间,谢谢!
[ 本帖最后由 onano 于 2010-2-5 11:16 编辑 ]
回复

使用道具 举报

千问 | 2011-12-29 15:35:34 | 显示全部楼层
是差不多的,因为查询的基数差不多,而且走索引,如果你加了条件,基数少很多,可能要快点
改变查询时间的因素太多了,索引只是其中一条,一切以执行计划为准,没有必要纠结这些无关紧要的东西
回复

使用道具 举报

千问 | 2011-12-29 15:35:34 | 显示全部楼层
谢谢ls
因为以前对系统不熟时
写的代码里有些这种情况,出现了重复的查询条件
既然不会有影响那就不用去修改了
回复

使用道具 举报

千问 | 2011-12-29 15:35:34 | 显示全部楼层
1. 走全表扫描的代价比走索引小,所以全表扫。
2. transaction_type_name='三' 这个没有用, 即使走索引默认的也是索引全扫描!

SQL> set autotrace off
SQL> desc test;
名称
是否为空? 类型
----------------------------------------------------------------------------------------------------------------- -------- ----------------------------------------------------------------------------
TRANSACTION_ID
NUMBER
TRANSACTION_TYPE_ID
NUMBER
TRANSACTION_TYPE_NAME
VARCHAR2(20)
SQL> select count(*) from test;
COUNT(*)
----------
10000000

SQL> set autotrace traceonly explain
SQL> select count(*) from test;

----------------------------------------------------------
Plan hash value: 1950795681
-------------------------------------------------------------------
| Id| Operation
| Name | Rows| Cost (%CPU)| Time
|
-------------------------------------------------------------------
| 0 | SELECT STATEMENT |
|
1 |6488 (5)| 00:01:18 |
| 1 |SORT AGGREGATE|
|
1 |
|
|
| 2 | TABLE ACCESS FULL| TEST |8796K|6488 (5)| 00:01:18 |
-------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
SQL> set linesize 2000
SQL> select /*+index(t i_trxn_type_id) */ * from test t where transaction_type_id=3
2/
----------------------------------------------------------
Plan hash value: 1252442098
----------------------------------------------------------------------------------------------
| Id| Operation
| Name
| Rows| Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT
|
| 294K|
10M| 29078 (1)| 00:05:49 |
| 1 |TABLE ACCESS BY INDEX ROWID| TEST
| 294K|
10M| 29078 (1)| 00:05:49 |
|*2 | INDEX RANGE SCAN
| I_TRXN_TYPE_ID | 294K|
| 672 (2)| 00:00:09 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TRANSACTION_TYPE_ID"=3)
Note
-----
- dynamic sampling used for this statement
SQL>
回复

使用道具 举报

千问 | 2011-12-29 15:35:34 | 显示全部楼层
也不一定就走full index scan的,和查询的数据块有很大关系,反正最好定时分析下表,让CBO自己判定走什么方式得了
回复

使用道具 举报

千问 | 2011-12-29 15:35:34 | 显示全部楼层
觉得应该是索引范围扫描
回复

使用道具 举报

千问 | 2011-12-29 15:35:34 | 显示全部楼层
表在会定期分析并且用cbo的情况下
只要 transaction_type_name='三' 这样的多余条件不会拖慢执行速度
那我就理解了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行