提问人:Lawrence Block 提问时间:11/3/2023 更新时间:11/4/2023 访问量:29
在 Oracle 中使用 null(带正则表达式)-非常慢
using null in Oracle (with regexp)-very slow
问:
试图弄清楚我可以做些什么来加快查询速度,就像当我尝试基于不为空返回值时一样 - 返回观察结果需要很长时间,我需要终止工作。正则表达式语句本身似乎没问题。
由于 IP 问题,我屏蔽了一些表名并更改了 var 名称。此外,我没有测试集,因为它在虚拟集中工作正常,但在实际生产环境中工作正常 - 这是它停滞不前的地方,所以我正在寻找解决此问题的一般概念。
任何意见/建议表示赞赏。谢谢。
select prev_pod.mrn_id, prev_pod.pat_enc_id, prev_pod.contact_date, note_text,
coalesce(REGEXP_substr(NOTE_TEXT, '(new)+{1,10}([^.|,|?|$])(wound)+{1,10}([^.|,|?|$])(evaluation)',1,1,'i'),
REGEXP_substr(NOTE_TEXT, '(foot)+{1,10}([^.|,|?|$])(wound)+{1,10}([^.|,|?|$])(clinic)+{1,10}([^.|,|?|$])(new)',1,1,'i')) as STR
from HNO_xxx inner join PREV_POD on HNO_xxx.pat_enc_id=prev_pod.pat_enc_id
inner join HNO_NOTE_TEXT ON HNO_xxx.note_id = HNO_NOTE_xxx.note_id and HNO_NOTE_xxx.LINE=1)
select * from ntes where STR IS NOT NULL); --THIS IS THE PROBLEM
答:
如前所述,Oracle 必须 100% 读取 并通过复杂的 REGEXP 逻辑运行其所有行,以满足您的谓词。为了加快速度,我建议首先使用并行性:HNO_NOTE_TEXT
WHERE str IS NOT NULL
select /*+ parallel(8) */ * from ntes where str is not null
第二件事是检查执行计划,看看计划是否改变了连接顺序。如果应用谓词 to(来自 ),它可能会以 和 join to 开头,然后按该顺序开头,而如果没有谓词,它可能会使用不同的连接顺序。如果这些联接列在一个方向上存在索引,但在另一个方向上没有索引,则可以解释运行时的差异。STR
HNO_NOTE_TEXT
HNO_NOTE_TEXT
HNO_xxx
PREV_POD
没有明显限制的谓词,因此您不希望在此处使用索引。检查计划,如果看到正在使用的索引,则可能需要使用提示来强制它执行全表扫描 + 哈希联接。它可能仅仅因为上面建议的并行提示而决定这样做,但如果没有,请编辑您的视图:/*+ USE_HASH(table_alias) */
select /*+ USE_HASH(hno_xxx prev_pod hno_note_text) PARALLEL(8) */ prev_pod.mrn_id, prev_pod.pat_enc_id, prev_pod.contact_date, note_text,
coalesce(REGEXP_substr(NOTE_TEXT, '(new)+{1,10}([^.|,|?|$])(wound)+{1,10}([^.|,|?|$])(evaluation)',1,1,'i'),
REGEXP_substr(NOTE_TEXT, '(foot)+{1,10}([^.|,|?|$])(wound)+{1,10}([^.|,|?|$])(clinic)+{1,10}([^.|,|?|$])(new)',1,1,'i')) as STR
from HNO_xxx inner join PREV_POD on HNO_xxx.pat_enc_id=prev_pod.pat_enc_id
inner join HNO_NOTE_TEXT ON HNO_xxx.note_id = HNO_NOTE_xxx.note_id and HNO_NOTE_xxx.LINE=1)
然后查询它:
select * from ntes where STR IS NOT NULL
请注意,如果其他人使用该视图并对其应用狭义谓词,这些提示将伤害他们。如果是这种情况,你最好不要使用视图,直接针对表编写 SQL,这样你的提示是私有的。
评论