【问题标题】:Efficiently delete columns based on mismatch from large tables根据大表中的不匹配有效地删除列
【发布时间】:2020-07-27 22:09:00
【问题描述】:

我有 2 个表,其架构如下所示:

key, host, file, mtimes
key, host

当键与表 2 相同但主机不同时,我必须从表 1 中删除所有行。

表 1(2500 万行):

k1, h0, file0, 0
k1, h1, file1, 0
k1, h2, file1, 1
k2, h3, file1, 2
k2, h3, file2, 3
k3, h4, file3, 4

表 2(30 万行):

k1, h0
k2, h3
k3, h4

结果:

k1, h0, file0, 0
k2, h3, file1, 2
k2, h3, file2, 3
k3, h4, file3, 4

【问题讨论】:

    标签: sql database sqlite


    【解决方案1】:

    在这种情况下,SQLite 中可供选择的选项并不多。
    你可以使用NOT EXISTS:

    delete from table1 
    where not exists (
      select 1 
      from table2 t2
      where t2.key = table1.key and t2.host = table1.host
    );
    

    两个表中(key, host) 的复合索引会有所帮助。

    请参阅demo
    结果:

    | key | host | file  | mtimes |
    | --- | ---- | ----- | ------ |
    | k1  | h0   | file0 | 0      |
    | k2  | h3   | file1 | 2      |
    | k2  | h3   | file2 | 3      |
    | k3  | h4   | file3 | 4      |
    

    【讨论】:

    • 你认为这样的大桌子性能好吗?
    • 我想不出 SQLite 提供的任何其他选项来满足此要求。所以设置索引,然后测试它。
    【解决方案2】:

    我认为带有相关子查询的 delete 可以满足您的需求:

    delete from table1
        where exists (select
                      from table2 t2
                      where t2.key = table1.key and t2.host <> t1.host
                     );
    

    如果只想选择符合条件的行,查询类似:

    select table1.*
    from table1
    where not exists (select
                      from table2 t2
                      where t2.key = table1.key and t2.host <> t1.host
                     );
    

    对于其中任何一个的性能,您都需要在table2(key, host) 上建立索引。

    【讨论】:

    • 这么大的桌子性能好吗?我运行了一个类似的查询,它基本上永远卡住了。
    猜你喜欢
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    相关资源
    最近更新 更多