如何优化接下来的oracle查询?
我有2张桌子。表“Accs”包含 900 万行(3 列:acc_id、月份、年份)。 首先我需要提取包含部分帐号条目的记录, 然后在这些记录中查找完整匹配,如果没有——则先查找部分匹配,
WITH t AS (
SELECT a.acc_id,
t1.as,
t1.cust,
t1.curr,
t1.code,
t1.depart,
t1.sdate,
t1.stype,
t1.amount,
t1.s_id
FROM table1 t1
LEFT JOIN Accs a
ON SUBSTR(a.acc_id,7,12)=t1.curr||LPAD(t1.code,4,'0')||LPAD(t1.depart,3,'0')
WHERE t1.sdate='20.11.2011' AND t1.stype='A' AND a.month=11 ANd a.year=2011)
SELECT MAX(t.s_id),
(CASE WHEN t.as='000000'
THEN (CASE WHEN ac2.acc_id IS NOT NULL THEN ac2.acc_id ELSE t.acc_id END)
ELSE t.cust||t.curr||LPAD(t.code,4,'0')||LPAD(t.depart,3,'0') END) acc_id
FROM t
LEFT JOIN (SELECT t.acc_id FROM t) ac2
ON SUBSTR(ac2.acc_id,1,6)='000'||LPAD(t.depart,3,'0')
GROUP BY
(CASE WHEN t.as='000000'
THEN (CASE WHEN ac2.acc_id IS NOT NULL THEN ac2.acc_id ELSE t.acc_id END)
ELSE t.cust||t.curr||LPAD(t.code,4,'0')||LPAD(t.depart,3,'0') END)
这样查询需要很长时间。我这样做是否正确?
I have 2 tables. Table "Accs" contains 9 million rows (3 columns: acc_id, month, year).
First I need to extract the records that contain the partial entry of account number,
and then in these records to find the complete match, if not - then the first partial match
WITH t AS (
SELECT a.acc_id,
t1.as,
t1.cust,
t1.curr,
t1.code,
t1.depart,
t1.sdate,
t1.stype,
t1.amount,
t1.s_id
FROM table1 t1
LEFT JOIN Accs a
ON SUBSTR(a.acc_id,7,12)=t1.curr||LPAD(t1.code,4,'0')||LPAD(t1.depart,3,'0')
WHERE t1.sdate='20.11.2011' AND t1.stype='A' AND a.month=11 ANd a.year=2011)
SELECT MAX(t.s_id),
(CASE WHEN t.as='000000'
THEN (CASE WHEN ac2.acc_id IS NOT NULL THEN ac2.acc_id ELSE t.acc_id END)
ELSE t.cust||t.curr||LPAD(t.code,4,'0')||LPAD(t.depart,3,'0') END) acc_id
FROM t
LEFT JOIN (SELECT t.acc_id FROM t) ac2
ON SUBSTR(ac2.acc_id,1,6)='000'||LPAD(t.depart,3,'0')
GROUP BY
(CASE WHEN t.as='000000'
THEN (CASE WHEN ac2.acc_id IS NOT NULL THEN ac2.acc_id ELSE t.acc_id END)
ELSE t.cust||t.curr||LPAD(t.code,4,'0')||LPAD(t.depart,3,'0') END)
This query takes a long time. Whether correctly I do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一次尝试
如果没有实际的表结构和数据,无法真正测试它,但我做了一些小的更改,有时确实会产生很大的影响。
首先,我将
with
部分中的LEFT JOIN
更改为INNER JOIN
。由于您在WHERE
子句中使用a
的值,因此它无论如何都会起到inner join
的作用,并且通常要快得多,尤其是有了这么多的数据和适当的索引。我将内部
CASE
更改为NVL
,因为这本质上就是它的作用。不知道这样会不会加快速度。将字符串连接从外部查询移至
with
部分。这些只是一些微小的变化,可能会产生从没有影响到相当大的影响。至少您可以在更改表结构本身之前尝试这些,尽管无论如何这样做可能是个好主意。
第二次尝试
在对您的查询进行了更多研究之后,我想知道您是否不能将其设为单个/简单查询,而不是使用
with
。我认为通过首先内部加入 Accs,然后在附加条件下再次加入 Accs,您确实是一个很好的方法。First attempt
Can't really test it without having your actual table structure and data, but I've made a few minor changes that do sometimes have big impact.
First of all, I changed the
LEFT JOIN
in thewith
part to anINNER JOIN
. Since you use values ofa
in theWHERE
clause, it would function as aninner join
anyway, and it is usually a lot faster, especially with this amount of data and proper indexes.I changed the inner
CASE
toNVL
, because that's essentially what it does. Don't know if that would speed things up.Moved the string concatenation from the outer query to the
with
part.These are just small changes that may have anywhere from no to quite some effect. At least you can try these before altering the table structure itself, although it may be a good idea to do that anyway.
Second attempt
After looking a little more into your query, I wonder if you cannot just make it a single/simple query instead of using
with
. I think by first inner joining Accs and then left joining Accs again with the extra condition, you're a good way to go really.您可以尝试创建基于函数的索引,如下所示:
You could try creating function-based indexes like this one: