【问题标题】:What is the best way, algorithm, method to difference large lists of data?区分大型数据列表的最佳方法、算法、方法是什么?
【发布时间】:2009-01-20 15:09:44
【问题描述】:

我每天都会收到大量当前帐号,并将它们存储在数据库中。我的任务是从每个文件中找到添加和释放的帐户。现在,我有 4 个 SQL 表(AccountsCurrent、AccountsNew、AccountsAdded、AccountsRemoved)。当我收到一个文件时,我会将它完全添加到 AccountsNew。然后运行以下查询以查找我们添加和删除的内容。

INSERT AccountsAdded(AccountNum, Name) SELECT AccountNum, Name FROM AccountsNew WHERE AccountNumber not in (SELECT AccountNum FROM AccountsCurrent)

INSERT AccountsRemoved(AccountNum, Name) SELECT AccountNum, Name FROM AccountsCurrent WHERE AccountNumber not in (SELECT AccountNum FROM AccountsNew)

TRUNCATE TABLE AccountsCurrent

INSERT AccountsCurrent(AccountNum, Name) SELECT AccountNum, Name FROM AccountsNew

TRUNCATE TABLE AccountsNew

目前,我正在区分大约 250,000 个帐户,但这会继续增长。这是最好的方法吗,您还有其他想法吗?

编辑: 这是一个 MSSQL 2000 数据库。我正在使用 c# 来处理文件。

我关注的唯一数据是在上一个文件和当前文件之间添加和删除的帐户。 AccountsCurrent,仅用于确定添加或删除了哪些帐户。

【问题讨论】:

  • 你最好去掉c#标签,这是一个直接的sql问题。
  • 另外,你能说一下你使用的是什么数据库吗?可能有 db 特定的优化。
  • 另外,不要使用IN语句,左外连接检查null,这样会快很多。

标签: c# sql algorithm


【解决方案1】:

老实说,我认为我会遵循您的方法。一件事是您可以删除截断,将“新”重命名为“当前”并重新创建“新”。

【讨论】:

    【解决方案2】:

    听起来像是一个历史记录/审计过程,最好使用触发器来完成。有一个单独的历史记录表来捕获更改(例如,时间戳、操作、执行更改的人员等)

    新帐户和已删除帐户很容易理解。 “当前”帐户意味着在新帐户和已删除帐户之间存在中间状态。我看不出“新”和“添加”之间有什么区别。

    我不会有四张桌子。我将有一个具有不同可能状态的 STATUS 表,并且 ACCOUNTS 或 HISTORY 表将有一个外键。

    【讨论】:

    • 问题是我不想在当前表中得到状态为“已删除”的帐户。我也不需要历史记录,我只需要当前文件中的添加和删除列表。当前列表确实与下一个文件一起使用,以确定是否添加或删除了帐户。
    【解决方案3】:

    在长列表上使用 IN 子句可能会很慢。

    如果表被索引,使用 LEFT JOIN 可以证明更快...

    INSERT INTO [table] (
        [fields]
        )
    SELECT
        [fields]
    FROM
        [table1]
    LEFT JOIN
        [table2]
            ON [join condition]
    WHERE
        [table2].[id] IS NULL
    

    这假设 1:1 关系,而不是 1:many。如果你有 1:many 你可以做任何...
    1. 选择不同
    2. 使用 GROUP BY 子句
    3. 使用不同的查询,见下文...

    INSERT INTO [table] (
        [fields]
        )
    SELECT
        [fields]
    FROM
        [table1]
    WHERE
        EXISTS (SELECT * FROM [table2] WHERE [condition to match tables 1 and 2])
    
    -- # This is quick provided that all fields to match the two tables are
    -- # indexed in both tables.  Should then be much faster than the IN clause.
    

    【讨论】:

    • 好提醒,我得做一些测试看看哪个更快
    【解决方案4】:

    您还可以减去交集以获得一张表中的差异。

    【讨论】:

      【解决方案5】:

      如果初始文件以合理且一致的方式排序(大 IF!),作为逻辑比较文件的 C# 程序,它将运行得更快。

      【讨论】:

      • 那很好,但它没有被订购。
      • 哦,好吧——排序文件加上比较的时间可能与基于 sql 的解决方案大致相同!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-13
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      相关资源
      最近更新 更多