ORACLE - 在大 table 上设置重复的 RANK,需要优化
ORACLE - Setting RANK of duplicated on a big table, optimization needed
这是更复杂算法的简化摘录。
问题是我有一个简单的 table C_HASH 像这样:
CREATE TABLE C_HASH
(
HASH CHAR (48),
RANK INTEGER
);
首先,我用所有哈希值填充 table。但是因为我可以在HASH中有重复项,为了一一识别重复项我需要通过HASH设置RANK。
我做了这个 SQL 语句但是它太长了,我已经索引了 HASH 列,但没有效果:
UPDATE C_HASH a set RANK = ( select temp.rank from ( select rowid, rank() over ( PARTITION BY HASH ORDER BY ROWID ) rank from C_HASH ) temp where temp.rowid = a.rowid);
我要优化这个!有线索吗?
这将花费很长时间,因为您要更新所有行。但是您可以将逻辑简化为:
update c_hash h
set rank = (select count(*)
from c_hash h2
where h2.hash = h.hash and h2.rowid <= h.rowid
);
这应该是 table 以利用您现有的索引。
您可以使用 merge
语法:
merge into c_hash c
using (
select rowid, row_number() over(partition by hash order by rowid) rank
from c_hash
) c1
on (c1.rowid = c.rowid)
when matched then update set c.rank = c1.rank
示例数据:
HASH | RANK
:----------------------------------------------- | ---:
foo | null
foo | null
foo | null
bar | null
结果:
HASH | RANK
:----------------------------------------------- | ---:
foo | 1
foo | 2
foo | 3
bar | 1
如果您要更新很多行,使用 insert ... select
语法创建一个新的 table 可能更有效:
create table c_hash2 as
select hash, row_number() over(partition by hash order by rowid) as rank
from c_hash
这是更复杂算法的简化摘录。 问题是我有一个简单的 table C_HASH 像这样:
CREATE TABLE C_HASH
(
HASH CHAR (48),
RANK INTEGER
);
首先,我用所有哈希值填充 table。但是因为我可以在HASH中有重复项,为了一一识别重复项我需要通过HASH设置RANK。
我做了这个 SQL 语句但是它太长了,我已经索引了 HASH 列,但没有效果:
UPDATE C_HASH a set RANK = ( select temp.rank from ( select rowid, rank() over ( PARTITION BY HASH ORDER BY ROWID ) rank from C_HASH ) temp where temp.rowid = a.rowid);
我要优化这个!有线索吗?
这将花费很长时间,因为您要更新所有行。但是您可以将逻辑简化为:
update c_hash h
set rank = (select count(*)
from c_hash h2
where h2.hash = h.hash and h2.rowid <= h.rowid
);
这应该是 table 以利用您现有的索引。
您可以使用 merge
语法:
merge into c_hash c
using (
select rowid, row_number() over(partition by hash order by rowid) rank
from c_hash
) c1
on (c1.rowid = c.rowid)
when matched then update set c.rank = c1.rank
示例数据:
HASH | RANK :----------------------------------------------- | ---: foo | null foo | null foo | null bar | null
结果:
HASH | RANK :----------------------------------------------- | ---: foo | 1 foo | 2 foo | 3 bar | 1
如果您要更新很多行,使用 insert ... select
语法创建一个新的 table 可能更有效:
create table c_hash2 as
select hash, row_number() over(partition by hash order by rowid) as rank
from c_hash