比如有一个表SysLog, 这张表有上百万条记录,字段有:
id Number 主键,
name varchar2(200),
addDate Date,
state varchar2(2),
content varchar2(500)
......查询条件 Where 子句 将是动态组装的,name, addDate, state 这几个条件可能有1到3个,其中addDate是肯定会出现在Where 子句中的。索引这样建吗?
create index SysLog_1_IDX on SysLog(addDate);
create index SysLog_2_IDX on SysLog(addDate, name)
create index SysLog_3_IDX on SysLog(addDate, name, state );... where name = ? and addDate >= ? --这样的顺序能否用到 索引:SysLog_2_IDX ?
... where addDate > ? and state = ? and content like ? --索引还起作用吗?
id Number 主键,
name varchar2(200),
addDate Date,
state varchar2(2),
content varchar2(500)
......查询条件 Where 子句 将是动态组装的,name, addDate, state 这几个条件可能有1到3个,其中addDate是肯定会出现在Where 子句中的。索引这样建吗?
create index SysLog_1_IDX on SysLog(addDate);
create index SysLog_2_IDX on SysLog(addDate, name)
create index SysLog_3_IDX on SysLog(addDate, name, state );... where name = ? and addDate >= ? --这样的顺序能否用到 索引:SysLog_2_IDX ?
... where addDate > ? and state = ? and content like ? --索引还起作用吗?
解决方案 »
- 数据库表按一字段状态分列汇总问题
- Oracle管道函数使用-编译错误-请教大虾
- 例子4:求出每一个部门里赚钱最多的那个人的名字
- 查询问题
- 如何一次创建多个存储过程,函数,触发器?
- 请教一个sql语句编写,把第一个不为0的数字前的所有0删掉
- sql的问题,不明白为什么是这个结果。
- oracle817下是否有类似于SQL SERVER 2000下的 inserted 和 deleted 表???各位大虾帮帮忙啊!!
- 怎样建一个用户帐户,把密码也加上,并且给他授予一个角色,用语句实现》
- 高手请看这个问题,解决马上给分
- oracle 根据某列值 统计个数[数据统计表页面SQL]
- sql case 查询
2、如果就只有你列举的两种语句来说,建立基于列addDate, name, state 的一个复合索引就够了。
3、上百万的记录,是最大规模,还是目前有百万记录,以后还会继续增长?如果继续增长,可以
考虑将表按addDate进行分区(使用分区表技术)。
4、实际情况需要优化器根据表的统计数据(数据量及分布)和查询条件的选择性来决定最优的执行计划。
5、你可以通过pl/sql developer f5键来查看执行计划。或者使用sqlplus下的explain plan for sql语句;
生成执行计划,使用select * from table(dbms_xplan.display);来查看执行计划。
再根据执行计划,若没有走索引,加 hint 。就可以了。
数据量大就建 个分区表
如果以后会增长到千万、亿记录数,建议还是增加分区,可以用addDate或者增加年月等字段来建立分区(在查询条件中相应增加)当前使用索引除非用HINT指定,否则数据库会计算COST来选择(统计值、数据分布等)
相 隐式类型转换,<>, like 都可能导致不走索引的
每次查询语句的时候,按顺序放where条件,如create index SysLog_3_IDX on SysLog(addDate, name, state ),你需要把addDate放在最前面。
还不如直接查数据库
在adddate建一个就可以了,你还要看看执行计划还有like可以走索引 的,只有一种情况 就是 like ‘aa%’
百分号在后面可以走索引
... where name = ? and addDate >= ? --这样的顺序不会用索引;
... where addDate > ? and state = ? and content like ? --仍然会用索引;