我有一个包含与员工相关的所有数据的 View 。 它有大约 350k 条记录。 我必须制作一个名称搜索功能。 这将检索与输入的关键字匹配的所有数据。
查询性能非常慢,需要 15-20 秒才能检索数据。 成本-15000
我的查询:
SELECT H.PERSON_ID,
B.EMPLOYEE_ID,
INITCAP(B.FIRST_NAME) EMP_FNAME,
INITCAP(B.MIDDLE_NAME) EMP_MNAME,
INITCAP(B.LAST_NAME) EMP_LNAME,
B.EMPLOYEE_TYPE PERSON_DESC,
B.EMPLOYMENT_STATUS STATUS_TYPE,
EA.BASE_BRANCH
FROM EMPLOYEE_BASIC_DTLS B,
EMP_ASSIGNMENT_DTLS_MV EA,
EMPLOYEE_HIS_DEPNDENT_TBL H
WHERE B.PERSON_ID = EA.PERSON_ID
AND B.PERSON_ID = H.PERSON_ID
AND ((UPPER(B.FIRST_NAME) LIKE
('%' || V_SEARCH_PARAM1 || '%')) OR
(UPPER(B.MIDDLE_NAME) LIKE
('%' || V_SEARCH_PARAM1 || '%')) OR
(UPPER(B.LAST_NAME) LIKE
('%' || V_SEARCH_PARAM1 || '%')))
AND TRUNC(SYSDATE) BETWEEN EA.EFFECTIVE_START_DATE AND
EA.EFFECTIVE_END_DATE
AND UPPER(H.RELATIONSHIP_CODE) = 'A';
由于 EMPLOYEE_BASIC_DTLS 是一个 View ,我无法使用索引。
最佳答案
虽然您确实无法在 View 上放置索引,但您当然可以在基础表上放置索引。但是,正如 @JustinCave 所指出的,即使您确实向相应的表添加了索引,该查询仍然不会使用它们,因为使用了 LIKE
。此外,由于 UPPER
函数应用于您需要的 FIRST_NAME
、MIDDLE_NAME
和 LAST_NAME
列将索引定义为基于函数的索引。例如,如果 EMPLOYEE_BASIC_TABLE
View 访问的“真实”表称为 EMPLOYEES
,您可以在 FIRST_NAME
列上定义基于函数的索引作为
CREATE INDEX EMPLOYEES_UPPER_FIRST_NAME ON EMPLOYEES (UPPER(FIRST_NAME));
我建议您考虑是否真的需要 LIKE 比较,因为解决这些问题以获得更好的性能将会很困难。
如果您想研究 Oracle Text 索引,您可以找到文档 here 。我想您会发现它更适合文档或文档片段索引,但也许它会给您一些想法。
分享并享受。
关于plsql - 优化oracle中的字符串搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18622559/