postgresql 优化从大表中删除

mitkmikd  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(2)|浏览(262)

告诉我如何优化从Postgre表中删除数据我有一个这样的表:

  1. CREATE TABLE IF NOT EXISTS test (
  2. group varchar(255),
  3. id varchar(255),
  4. type varchar(255),
  5. );
  6. INSERT INTO test
  7. (group, id, type)
  8. VALUES
  9. ('1', 'qw', 'START'),
  10. ('1', 'er', 'PROCESS'),
  11. ('1', 'ty', 'FINISH');
  12. INSERT INTO test
  13. (group, id, type)
  14. VALUES
  15. ('2', 'as', 'START'),
  16. ('2', 'df', 'PROCESS'),
  17. ('2', 'fg', 'ERROR');
  18. INSERT INTO test
  19. (group, id, type)
  20. VALUES
  21. ('3', 'zx', 'START'),
  22. ('3', 'cv', 'PROCESS'),
  23. ('3', 'ty', 'ERROR');
  24. INSERT INTO test
  25. (group, id, type)
  26. VALUES
  27. ('4', 'df', 'START'),
  28. ('4', 'gh', 'PROCESS'),
  29. ('4', 'fg', 'ERROR'),
  30. ('4', 'ty', 'FINISH');

| 组群|标识符|类型|
| - -|- -|- -|
| 一个|每周一次|启动|
| 一个|额|工艺流程|
| 一个|泰|表面处理|
| 2个|作为|启动|
| 2个|深度|工艺流程|
| 2个|fg值|错误信息|
| 三个|zx型|启动|
| 三个|CV值|工艺流程|
| 三个|泰|错误信息|
| 四个|深度|启动|
| 四个|生长激素|工艺流程|
| 四个|光纤陀螺仪|错误信息|
| 四个|泰|表面处理|
它包含由GROUP字段中的一个值组合的操作但并非所有操作都到达末尾,并且列表中没有值为FINISH的操作,但具有类型ERROR,如GROUP 2和GROUP 3的行此表为1 TB我想删除所有未以FINISH状态结束的操作链,优化此操作的最佳方法是什么?
我的程式码如下所示:

  1. delete from TEST for_delete
  2. where
  3. for_delete.group in (
  4. select group from TEST error
  5. where
  6. error.type='ERROR'
  7. and
  8. error.group NOT IN (select group from TEST where type='FINISH')
  9. );

但是对于这样一个体积的盘子,我想它会慢得可怕,我能以某种方式改进我的代码吗?

hm2xizp9

hm2xizp91#

EXISTS条件通常比IN条件更快,而NOT EXISTS几乎总是比NOT IN更快,所以你可以这样尝试:

  1. delete from test t1
  2. where exists (select *
  3. from test t2
  4. where t2."group" = t1."group"
  5. and t2."type" = 'ERROR'
  6. and not exists (select
  7. from test t3
  8. where t3."group" = t2."group"
  9. and t3."type" = 'FINISH'));
xoefb8l8

xoefb8l82#

通常,在这种情况下,您应该使用MV(实体化视图)。您可以创建一个表,在其中保存需要删除的所有ID,并使用触发器保持同步。例如:

  1. CREARE TABLE IF NOT EXISTS test_MV (
  2. id VARCHAR(255) PRIMARY KEY
  3. );

您知道您使用的系统和数据,也可以决定使用事件来保持数据表同步。使用MV,您可以使用更简单、更快速的方式来删除所有数据列:

  1. delete from TEST for_delete
  2. where
  3. for_delete.id in (
  4. select id from test_MV
  5. );

对不起我的英语不好

相关问题