比如有一个表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 ? --索引还起作用吗?

解决方案 »

  1.   

    1、一个表上的索引最好不要超过5个,索引太多可能会影响插入和更新的性能。
    2、如果就只有你列举的两种语句来说,建立基于列addDate, name, state 的一个复合索引就够了。
    3、上百万的记录,是最大规模,还是目前有百万记录,以后还会继续增长?如果继续增长,可以
       考虑将表按addDate进行分区(使用分区表技术)。
    4、实际情况需要优化器根据表的统计数据(数据量及分布)和查询条件的选择性来决定最优的执行计划。
    5、你可以通过pl/sql developer f5键来查看执行计划。或者使用sqlplus下的explain plan for sql语句;
       生成执行计划,使用select * from table(dbms_xplan.display);来查看执行计划。
      

  2.   

    建最后一个复合索引就可以了。
    再根据执行计划,若没有走索引,加 hint 。就可以了。
    数据量大就建 个分区表
      

  3.   

    3楼很详细了建索引在不分区的情况下,create index SysLog_3_IDX on SysLog(addDate, name, state ); 复合索引就够了
    如果以后会增长到千万、亿记录数,建议还是增加分区,可以用addDate或者增加年月等字段来建立分区(在查询条件中相应增加)当前使用索引除非用HINT指定,否则数据库会计算COST来选择(统计值、数据分布等)
      

  4.   

    3楼解释了很多 还有就是  并不是where里出现的字段就会走到索引
    相 隐式类型转换,<>, like 都可能导致不走索引的
      

  5.   

    create index SysLog_3_IDX on SysLog(addDate, name, state )建立一个就够了,当建立复合索引时,要注意前导列,就是把经常查询要用到放到最前面。
      

  6.   

    建立一个索引就可以了,但是你需要注意的是:
       每次查询语句的时候,按顺序放where条件,如create index SysLog_3_IDX on SysLog(addDate, name, state ),你需要把addDate放在最前面。
      

  7.   

    建索引不能乱建的你state ,name重复的比较多吧 不建议建这个联合索引,这样的话
    还不如直接查数据库
    在adddate建一个就可以了,你还要看看执行计划还有like可以走索引 的,只有一种情况 就是 like ‘aa%’
    百分号在后面可以走索引
      

  8.   

    实践证明:
    ... where name = ? and addDate >= ? --这样的顺序不会用索引;
    ... where addDate > ? and state = ? and content like ? --仍然会用索引;