我有一个7列的表.
它将包含大量的数据 – 每月将添加超过170万条记录.
在这7列中,我将在不同组合中对此表的查询的WHERE子句中使用5列.
可以为这些可能的组合创建不同的索引吗?
我问这个问题,因为如果我这样做,这张桌子上会有超过10个索引,我不确定这是不是一个好主意.
另一方面,我害怕在没有索引的情况下查询包含大量数据的表.
这是表格:
CREATE TABLE AG_PAYMENTS_TO_BE ( PAYMENTID NUMBER(15,0) NOT NULL,DEPARTID NUMBER(3,0),PENSIONERID NUMBER(11,AMOUNT NUMBER(6,2),PERIOD CHAR(6 CHAR),PAYMENTTYPE NUMBER(1,ST NUMBER(1,0) DEFAULT 0,CONSTRAINT AG_PAYMENTS_TO_BE_PK PRIMARY KEY ( PAYMENTID ) ENABLE );
可能的查询:
>从AG_PAYMENTS_TO_BE中选择AMOUNT,其中ST = 0 AND DEPARTID = 112 AND PERIOD =’201207′;
>从AG_PAYMENTS_TO_BE中选择AMOUNT,其中ST = 0且PENSIONERID = 123456 AND PERIOD =’201207′;
>从AG_PAYMENTS_TO_BE中选择AMOUNT,其中ST = 0且PENSIONERID = 123456 AND PERIOD =’201207’AND PAYMENTTYPE = 1;
>从AG_PAYMENTS_TO_BE中选择AMOUNT,其中ST = 0且DEPARTID = 112且ST = 0;
>从AG_PAYMENTS_TO_BE中选择AMOUNT,其中ST = 0且PENSIONERID = 123456;
等等.
解决方法
暂时忽略索引跳过扫描*,以便查询使用索引:
>必须在查询中列出前导索引列
>他们必须使用精确连接进行比较(即使用=,而不是<,>或类似)
例如,在(a,b)上具有复合索引的表可以使用以下查询中的索引:
> a =:b1和b> =:b2
> a =:b1
但不是:
> b =:b2
因为列b在索引中排在第二位. *在某些情况下,索引可以通过index skip scan在这种情况下使用.这是跳过索引中的前导列的位置.然而,第一列需要相对较少的不同值,这不经常发生(根据我的经验).
请注意,只使用其中某些前导列的查询可以使用“更大”的索引.所以在上面的例子中,只有a的索引是多余的,因为显示的查询可以使用a,b上的索引.然而,仅b的索引可能是有用的.
您添加的索引越多,插入/更新/删除的速度就越慢,因为索引必须与表同时维护.因此,您的目标应该是保持索引数量下降,除非添加新索引有显着的查询优势.这是您必须在您的环境中测量的,以确定确切的成本/收益.
请注意,具有相似列的多个索引可以导致wrong index being selected.因此,当您有许多类似的索引时,选择可能存在缺点.解析时间也略有开销,因为Oracle在选择执行计划时有更多选择.
查看您的查询我相信您只需要索引:
> st,departid,period
> st,养老金,期间
您可能希望在这些末尾添加金额,这样您的查询就可以从索引中完全回答,从而节省了表查找.如果这些列是其他表的外键,则可能还需要其他索引,to prevent locking issues.