索引不会提高性能,有时会使情况变得更糟

Mik*_*ham 2 sql oracle indexing performance oracle11g

我有一张桌子EMPLOYEE(EMP_ID, EMP_NAME, DESC, SALARY),我想找回所有可以做魔术的员工.如果每个员工都存储在每个员工的每个DESC条目的末尾,那么能够执行魔术就被归类为人才和人才.

如果一个员工有任何才能,那么该DESC员工的最终结果就是'Talent: __talent_here__'.例如,乔擅长杂耍,然后他的描述就像是'Joe Doe, works here since 2011. Talent: juggling'.我可以假设,在每一个描述有字符串常量只有一个实例'Talent: ',人才总是存储在的结束DESC,而不是所有的员工都有人才.我还想对按名称检索的员工进行排序,我只想要前50个排序值

这是SELECT我目前正在发表的声明.

SELECT * FROM (
    SELECT E.EMP_NAME FROM EMP E
    WHERE INSTR(E.DESC, 'Talent: ') > 0
        AND INSTR(SUBSTR(E.DESCRIPTION, INSTR(E.DESC, 'Talent: ')), 'magic') > 0
    ORDER BY E.EMP_NAME ASC
) WHERE ROWNUM <= 50
/
Run Code Online (Sandbox Code Playgroud)

这个SELECT说法很好.现在我想在查询上创建索引以改善运行时间:

CREATE INDEX MAGICIANS ON EMP(
    INSTR(DESCRIPTION, 'Talent: '), 
    INSTR(SUBSTR(DESCRIPTION, INSTR(DESCRIPTION, 'Talent: ')), 'magic'))
/
Run Code Online (Sandbox Code Playgroud)

但这个指数似乎不起作用.我在我的表中有大约9000个条目,在创建索引之前,我的select语句的运行时间是00.50秒.创建索引后,它变为大约00.49秒.我一直在试验索引,有时创建索引后的运行时甚至比之前略差.(从00.50到00.52秒)

有谁知道为什么会这样?

感谢大家.

APC*_*APC 5

索引不是魔术(噢喔!).构建索引并不能保证更快的检索时间.要理解为什么索引不能提供更快的结果,您需要了解索引的工作原理.

您的索引按"Talent"一词的偏移量排列.没有人才的所有员工都有零抵消,所有其他员工都有更大的数字.对于他们来说,偏移量是其值的长度的函数DESCRIPTION.至关重要的是(可能)DESCRIPTION员工的长度和员工是否可以做魔术之间没有任何关系.

因此,要查找可以执行魔术的员工,数据库必须访问talent偏移量不为零的所有索引条目,然后读取偏移量不为零的所有索引条目magic,然后读取这些条目的表记录.魔术师的索引条目将分散在索引中,并且这些记录将分散在整个表中.几乎可以肯定,进行全表扫描并从表中提取记录会更快.

另一件事是,即使你的指数对魔术师起作用,找到变戏法者也没用.

从根本上说,这是数据模型的失败:嵌入TALENT在DESCRIPTION休息第一范式.为什么有可能解决它 - 使用虚拟列(或像@TimBiegeisen建议的物化视图) - 正确的解决方案是建模TALENT为查找表并EMPLOYEE通过外键引用它(从而消除员工练习的可能性' magick'或'Majik').这样的查找表还可以让您拥有多才多艺的员工:您可以使用交叉表EMPLOYEE_TALENT为魔术师和玩杂耍的员工建模,以加入EMPLOYEE和TALENT表.