【问题标题】:sql join tales with likesql用like连接表
【发布时间】:2014-02-28 08:26:42
【问题描述】:

我在 Postgres 中有两个表,电子邮件有 10.000.000 行,而 spam_email 有 150.000 行。电子邮件表由普通电子邮件地址组成,如“example@domain.com”、“example1@domain2.com”等,垃圾邮件表由“@domain.com”、“@domain1.com”等地址组成。

我想做的是从 emails 表中找到与 spam_email 表匹配的所有值。 我所做的是这段代码:

Insert INTO clean_email(email) 
select distinct email 
from email e 
   join (select email from spam_email) se ON se.email not like s.email

但每次我收到错误disk out of space

您还有其他解决方案吗? 谢谢

【问题讨论】:

  • 你为什么不考虑从 email 表中删除垃圾邮件而不是复制大约。 (10.000.000 - 150.000) 行放入另一个表,即 clean_email?您不会丢失任何数据,因为已删除的数据仍会存在于 spam_email 表中,而 email 表只会存储干净的电子邮件?
  • @zibidyum 谢谢你的想法。我现在试一试,我会告诉你它是否有效。再次感谢
  • 我是否理解正确,您希望 clean_emails 包含垃圾邮件表中没有域的电子邮件?
  • @harmic 是的。垃圾邮件表可能包含完整地址以及 example@example_domain.com
  • @zibidyum 即使删除语句​​也返回错误:设备上没有剩余空间

标签: sql postgresql join sql-like


【解决方案1】:

如果您的磁盘空间不足,那么您可能需要更多磁盘空间;或者您可能需要配置 postgresql 以更好地利用可用资源:https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server

话虽如此,没有必要加入子选择,并且可能正在将资源用于临时表或排序,这是可以避免的。

您的查询不可能按照书面形式运行(没有名为 s 的表,因此 s.email 不可能正确)。

试试这个:

从电子邮件 e 中选择不同的 se.email 加入 spam_email se ON e.email NOT LIKE '%' || se.email;

这仍然是一个缓慢的查询计划;没有办法使用索引进行像like '%' || se.email 这样的查询,所以它会进行大量的表扫描。最好将域部分分成另一列并在其上放置索引(或为其使用函数并在函数上放置索引)。

【讨论】:

  • 具体来说,您的temp_tablespaces 没有足够的空间用于为合并连接或排序写入的临时文件。
【解决方案2】:
Insert INTO clean_email(email) 
select distinct email 
from email e 
   left join spam_email se ON se.email=e.email
where se.email is null;

【讨论】:

    【解决方案3】:

    您正在尝试将 èmail 中的记录与 not like 电子邮件中的每条记录进行匹配,这将产生大约 10000000 x 150000 条记录,从而导致空间不足。

    假设spam_email 存储诸如'@domain1.com' 之类的记录,我认为下面的查询会更接近您想要完成的任务。

    insert into clear_email(email)
    select distinct
      e.email
    from email e
    inner join spam_email se on extract_domain_from_mail(e.email) = se.email
    

    【讨论】:

      猜你喜欢
      • 2011-07-10
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2014-07-12
      相关资源
      最近更新 更多