Regex 在oracle中更新的更快方法
我有一个表,其recordid列如下Regex 在oracle中更新的更快方法,regex,oracle,sqlplus,Regex,Oracle,Sqlplus,我有一个表,其recordid列如下 recordid ---------- 1001 1002 1003... 以及另一个表,其中记录ID保存在自定义的分隔字符串中,如 col1 ------- 1001|1002|... |1003|1001|... |||1002|... 我想删除第二个表中某些记录ID的所有匹配项-例如1001。目前,我正在使用PHP脚本中的replace进行更新,但由于记录量太大,它正在超时-第二个表有2000多万条记录 有没有其他更快的方法来实现同样的目标?我目前
recordid
----------
1001
1002
1003...
以及另一个表,其中记录ID保存在自定义的分隔字符串中,如
col1
-------
1001|1002|...
|1003|1001|...
|||1002|...
我想删除第二个表中某些记录ID的所有匹配项-例如1001。目前,我正在使用PHP脚本中的replace进行更新,但由于记录量太大,它正在超时-第二个表有2000多万条记录
有没有其他更快的方法来实现同样的目标?我目前正在尝试使用正则表达式,但不确定这是否会更快。欢迎提出任何建议/建议
编辑1:
要更新的当前代码-正在超时-
update table2 set col1 = replace(col1, '1001', '')
where col1 like '%|1001|%'
or col1 like '1001|%'
这只是一个例子;由于有数百万行,我不知道它将如何执行,即它是否至少比您的
替换
快一点。无论如何,看看,如果你想试试
首先测试用例:
SQL> create table first (id number);
Table created.
SQL> create table second (id number, col1 varchar2(30));
Table created.
SQL> insert all
2 into first values (1001)
3 into first values (1002)
4 into first values (1003)
5 --
6 into second values (1, '1001|1002|1006')
7 into second values (2, '|1003|1001|1004')
8 into second values (3, '|||1002|1007|1008')
9 select * from dual;
6 rows created.
SQL>
由于第二个表中有一个唯一标识行的ID
列(如您在注释中所述),因此可以使用该列创建一个新的临时表,将其COL1
列拆分为行<代码>ID稍后将用于返回剩余值(在列表中)
现在,删除第一个表中存在的值是一项简单的任务;检查哪些铰孔:
SQL> delete from second_temp t where t.val in (select f.id from first f);
5 rows deleted.
SQL> select * from second_temp order by id, rn;
ID RN VAL
---------- ---------- ----------
1 3 1006
2 3 1004
2 4
3 2 1007
3 3 1008
3 4
3 5
3 6
8 rows selected.
SQL>
让我们将剩余值聚合回col1
:
SQL> select t.id, listagg(t.val, '|') within group (order by t.rn) col1
2 from second_temp t
3 group by t.id;
ID COL1
---------- --------------------
1 1006
2 1004
3 1007|1008
SQL>
现在,它将被用来做什么?我不知道;您可以将其用作CTA(创建表为Select)并创建一个全新的第二个表。或者,您可以截断原始的第二个表并将这些值插入其中。或这只是一个例子;由于有数百万行,我不知道它将如何执行,即它是否至少比您的替换
快一点。无论如何,看看,如果你想试试
首先测试用例:
SQL> create table first (id number);
Table created.
SQL> create table second (id number, col1 varchar2(30));
Table created.
SQL> insert all
2 into first values (1001)
3 into first values (1002)
4 into first values (1003)
5 --
6 into second values (1, '1001|1002|1006')
7 into second values (2, '|1003|1001|1004')
8 into second values (3, '|||1002|1007|1008')
9 select * from dual;
6 rows created.
SQL>
由于第二个表中有一个唯一标识行的ID
列(如您在注释中所述),因此可以使用该列创建一个新的临时表,将其COL1
列拆分为行<代码>ID
稍后将用于返回剩余值(在列表中)
现在,删除第一个表中存在的值是一项简单的任务;检查哪些铰孔:
SQL> delete from second_temp t where t.val in (select f.id from first f);
5 rows deleted.
SQL> select * from second_temp order by id, rn;
ID RN VAL
---------- ---------- ----------
1 3 1006
2 3 1004
2 4
3 2 1007
3 3 1008
3 4
3 5
3 6
8 rows selected.
SQL>
让我们将剩余值聚合回col1
:
SQL> select t.id, listagg(t.val, '|') within group (order by t.rn) col1
2 from second_temp t
3 group by t.id;
ID COL1
---------- --------------------
1 1006
2 1004
3 1007|1008
SQL>
现在,它将被用来做什么?我不知道;您可以将其用作CTA(创建表为Select)并创建一个全新的第二个表。或者,您可以截断原始的第二个表并将这些值插入其中。或其他内容。如果需要帮助修复查询,请显示查询。这两个表之间的关系是什么?是否要删除第二个表中第一个表中的所有ID?通常,在关系数据库中的单个列中存储事物列表是一个坏主意。这个问题就是一个很好的例子。@Barmar-我完全同意这是个坏主意。遗留代码,这可能是修复它的第一步,如果您有一个类似|1001 | 11001
的列,则查询会将其转换为| 1
显示您的查询,如果您需要帮助修复它。这两个表之间的关系是什么?是否要删除第二个表中第一个表中的所有ID?通常,在关系数据库中的单个列中存储事物列表是一个坏主意。这个问题就是一个很好的例子。@Barmar-我完全同意这是个坏主意。遗留代码,这可能是修复它的第一步,如果您有一个类似|1001 | 11001
的列,查询会将其转换为| 1
,请欣赏您的努力。让我尝试一下这种方法,看看能否解决这个问题。谢谢,我删除了我的备选答案。这种方法,或者类似的方法,似乎要快得多。我最后用正则表达式过滤了一个临时表的值,然后将临时表与实际的临时表合并。仍然需要很长时间,但比以前快多了。感谢您的努力。让我尝试一下这种方法,看看能否解决这个问题。谢谢,我删除了我的备选答案。这种方法,或者类似的方法,似乎要快得多。我最后用正则表达式过滤了一个临时表的值,然后将临时表与实际的临时表合并。仍然需要很长时间,但比以前快得多。