SQL优化 - 字符串中的字数 - Postgresql

Mul*_*one 4 sql postgresql parallel-processing optimization

我正在尝试使用Postgresql上字段中的单词计数来更新一个大表(大约1M行).此查询有效,并设置token_count计算表中单词(标记)longtext的字段my_table:

UPDATE my_table mt SET token_count = 
    (select count(token) from 
      (select unnest(regexp_matches(t.longtext, E'\\w+','g')) as token
      from my_table as t where mt.myid = t.myid)
    as tokens);
Run Code Online (Sandbox Code Playgroud)

myid是表的主键. \\w+是必要的,因为我想数字,忽略特殊字符.例如,A test . ; )将返回5,基于空格的计数,而2是正确的值.问题是它非常慢,2天不足以在1M行上完成它.你会做些什么来优化它?有没有办法避免加入?

如何使用例如limit和批处理将批处理拆分为块offset?

谢谢你的提示,

Mulone

更新:我测量了array_split的性能,无论如何更新都会很慢.因此,解决方案可能包括并行化.如果我运行不同的查询psql,只有一个查询有效,其他查询等待它完成.如何并行更新?

Den*_*rdy 7

你试过用过array_length吗?

UPDATE my_table mt
SET token_count = array_length(regexp_split_to_array(trim(longtext), E'\\W+','g'), 1)
Run Code Online (Sandbox Code Playgroud)

http://www.postgresql.org/docs/current/static/functions-array.html

# select array_length(regexp_split_to_array(trim(' some long text  '), E'\\W+'), 1);
 array_length 
--------------
            3
(1 row)
Run Code Online (Sandbox Code Playgroud)


DVK*_*DVK -2

  1. 确保myid已建立索引,成为索引中的第一个字段。

  2. 首先考虑在数据库之外执行此操作。没有基准测试很难说,但是计数可能比 select+update 成本更高;所以可能是值得的。

    • 使用 COPY 命令(Postgres 的 BCP 等效命令)将表数据有效地批量复制到文件中

    • 运行一个简单的 Perl 脚本进行计数。对于 Perl,100 万行应该需要几分钟到 1 小时,具体取决于 IO 的速度。

    • 使用 COPY 将表复制回数据库(可能复制到临时表中,然后从该临时表进行更新;或者更好的是截断主表并直接 COPY 到其中,如果您可以承受停机时间)。

  3. 对于您的方法以及我的方法 #2 的最后一步,以 5000 行为一批更新 token_count(例如,将 rowcount 设置为 5000,然后循环添加where token_count IS NULL到查询中的更新)