Каков наилучший способ, алгоритм, метод для различия больших списков данных? - PullRequest
1 голос
/ 20 января 2009

Я ежедневно получаю большой список номеров текущих счетов и храню их в базе данных. Моя задача - найти добавленные и освобожденные учетные записи из каждого файла. Прямо сейчас у меня есть 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 учетных записей, но это будет расти. Это лучший метод, у вас есть другие идеи?

EDIT: Это база данных MSSQL 2000. Я использую c # для обработки файла.

Единственные данные, на которых я сосредоточен, - это учетные записи, которые были добавлены и удалены между последним и текущим файлами. AccountsCurrent, используется только для определения того, какие учетные записи были добавлены или удалены.

Ответы [ 5 ]

1 голос
/ 20 января 2009

Если честно, я думаю, что следовал бы чему-то вроде вашего подхода. Во-первых, вы можете удалить усечение, переименовать «новый» в «текущий» и заново создать «новый».

1 голос
/ 20 января 2009

Использование предложений 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: многие. Если у вас есть 1: много, вы можете сделать любое из ...
1. ВЫБЕРИТЕ DISTINCT
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.
1 голос
/ 20 января 2009

Походит на историю / процесс аудита, который мог бы быть лучше сделан с использованием триггеров. Иметь отдельную таблицу истории, в которой фиксируются изменения (например, отметка времени, операция, кто выполнил изменение и т. Д.)

Новые и удаленные учетные записи легко понять. «Текущие» учетные записи подразумевают наличие промежуточного состояния между новым и удаленным. Я не вижу никакой разницы между «новым» и «добавленным».

У меня не было бы четырех столов. У меня была бы таблица STATUS, в которой были бы разные возможные состояния, а таблица ACCOUNTS или таблица HISTORY имели бы внешний ключ.

0 голосов
/ 20 января 2009

Если исходный файл упорядочен разумным и последовательным способом (большой IF!), Он будет работать значительно быстрее, чем программа C #, которая логически сравнивает файлы.

0 голосов
/ 20 января 2009

Вы также можете вычесть пересечение, чтобы получить различия в одной таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...