【问题标题】:find the difference between two very large list找出两个非常大的列表之间的区别
【发布时间】:2011-02-07 09:02:15
【问题描述】:

我有两个大列表(可能是一亿个项目),每个列表的来源可以来自数据库表或平面文件。两个列表的大小相当,均未排序。我需要找出它们之间的区别。所以我有 3 个场景:
1. List1 是一个数据库表(假设每一行只有一个 item(key) 是一个字符串),List2 是一个大文件。
2. 两个列表都来自 2 个数据库表。
3. 两个列表都来自两个文件。


在情况2中,我打算使用:

从 MyTable a 中选择 a.item,其中 a.item 不在(从 MyTable b 中选择 b.item)

这显然是低效的,有没有更好的方法?

另一种方法是:
我计划对每个列表进行排序,然后沿着它们两个方向查找差异。如果列表来自文件,我必须先将其读入 db 表,然后使用 db 排序输出列表。 db排序中的运行时间复杂度仍然是O(nlogn)吗?

当涉及的列表包含数亿个项目时,任何一种方法都是一种痛苦并且似乎会很慢。有什么建议么?

【问题讨论】:

    标签: database sorting


    【解决方案1】:

    这不是一个真正的数据库问题。

    第 1 步。对两个列表进行排序。也许数据库列表已经排序,但如果没有,则以排序顺序导出它,或者如果需要多次排序相同的列表,则创建索引。

    步骤 2. 使用排序实用程序在文本文件中制作列表的排序副本。如果这些列表超出了 UNIX 排序实用程序的能力,请将它们分解,对每个列表进行排序,然后在您的应用程序中包含这些列表的合并。

    第 3 步。编写您的应用程序以对两个列表应用合并算法,并以这种方式识别差异。请注意,如果文本文件有很多块,则需要辅助合并算法以按排序顺序提供主算法。

    请注意,如果您无法使用 UNIX 或 Linux 对文本文件进行排序,请获取 UNIX 排序命令的源代码并将其移植到您的操作系统。 This article explains why.

    【讨论】:

    • +1 这是唯一正确的答案。 DB 不是为此而设计的,当您谈论 100 的数百万行时表现不佳。我最有趣的项目之一是为直接营销编写一个合并系统,它的工作原理与 Mitch 在这里描述的完全一样。
    • 这绝对比简单的 db left join 更痛苦(在 Chri 的回答中): select a.item from MyTable a LEFT JOIN MyTable B ON A.JoinColumn = B.JoinColumn where B.JoinColumn IS NULL,但无论如何,db 排序不会比 unix 排序实用程序或我自己分解它们然后在我的应用程序中排序的方式更有效吗?
    【解决方案2】:
    1. 在所有情况下都将这两个集合放入数据库中...这种排序和确定是 db 的用途。其他任何事情都会重新发明轮子。
    2. 以下可能会比 NOT IN 更快(但请测试以确保):

      从 MyTable 中选择 a.item a LEFT JOIN MyTable B ON A.JoinColumn = B.JoinColumn where B.JoinColumn IS NULL

    确保您的 JoinColumns 已编入索引。索引将使整个排序问题变得扑朔迷离。

    【讨论】:

    • 在 SQL Server 中,您的第 2 点绝对不正确。 (在 MySQL 中我认为它可能是正确的)。在 SQL Server 中,虽然我可能只会做select item from a except select item from b
    • 对于每个表 1 亿行来说,这样的左连接是否非常慢?
    猜你喜欢
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 2011-09-06
    • 2012-05-12
    • 2018-11-12
    • 1970-01-01
    • 2014-10-22
    • 2021-09-30
    相关资源
    最近更新 更多