Соответствие двум большим таблицам SQLITE3 - PullRequest
1 голос
/ 14 января 2010

У меня есть две таблицы:

t1: f1, f2, f3, f4, rowid_t2, sts

t2: f1, f2, f3, f4, sts

с различным количеством записей, превышающим 10 миллионов.

Мне нужно сопоставить их, используя f1, f2 и f3 каждой таблицы в качестве ключей, соотношение
, что одна запись t1 может совпадать с одной записью в t2 или множеством записей t1 может соответствовать одной записи в t2, соответствие зависит от условий, указанных в трех операциях ниже.


Мне нужно выполнить следующие соответствующие операции:

a) Если t1.f1 = t2.f1 и t1.f2 = t2.f2 и t1.f3 = t2.f3, тогда я должен обновить идентификатор строки t2 до t1.rowid_t2 и сохранить t1.sts=1, t2.sts=1 в соответствующих записях .

b) Если t1.f1 = t2.f1 и t1.f2 = t2.f2 и t1.f3 <> t2.f3, тогда я должен обновить идентификатор строки t2 до rowid_t2 и сохранить t1.sts=2, t2.sts=2 в найденных записях .

c) Если t1.f1 = t2.f1 и t1.f2 <> t2.f2 и t1.f3 <> t2.f3, тогда я должен обновить идентификатор строки T2 в rowid_t2 и сохранить t1.sts=3, t2.sts=3 в найденных записях.


У меня есть 2 вопроса:

  1. Можно ли решить проблему с помощью UPDATE? Если да, было бы хорошо, если бы вы могли показать мне решение только для а)

  2. Сколько индексов я должен создать, чтобы оптимизировать необходимые ОБНОВЛЕНИЯ и ВЫБОРЫ для трех операций?

Ответы [ 2 ]

0 голосов
/ 15 января 2010

У меня нет опыта работы с SQLite, но я попробовал вашу проблему.

Как вы уже сказали, невозможно обновить более одной таблицы одновременно (насколько мне известно, решение , предоставляемое Tristran , работает только для MySQL.

Сначала я обновляю t1 и устанавливаю sts=1 для каждой строки (если затронуто только несколько строк, может быть более эффективно добавить условие WHERE для получения соответствующих строк) и rowid_t2 t2.rowid, где все соответствующие столбцы совпадают.

UPDATE t1
SET
  sts = 1, 
  rowid_t2 = (
    SELECT rowid FROM t2
    WHERE t2.f1 = t1.f1 AND t2.f2 = t1.f2 AND t2.f3 = t1.f3
  );

Затем я делаю то же самое с sts=2 и sts=3, но только там, где rowid_t2 еще не установлено.

UPDATE t1
SET
  sts = 2, 
  rowid_t2 = (
    SELECT rowid FROM t2
    WHERE t2.f1 = t1.f1 AND t2.f2 = t1.f2
  )
WHERE t1.rowid_t2 IS NULL;

UPDATE t1
SET
  sts = 3, 
  rowid_t2 = (
    SELECT rowid FROM t2
    WHERE t2.f1 = t1.f1
  )
WHERE t1.rowid_t2 IS NULL;

Затем я сбрасываю t1.sts, которые были установлены на 3, но на самом деле не действительны:

UPDATE t1
SET sts = NULL
WHERE rowid_t2 IS NULL;

И, наконец, я обновляю sts в t2 до "самого низкого" метода, который соответствовал t1. Поэтому, если строка в t2 имеет одну строку в t1, которая соответствует всем критериям, и строку, которая соответствует только для f1, я все равно устанавливаю sts=1.

UPDATE t2
SET sts = (
  SELECT MIN(sts)
  FROM t1
  WHERE t1.rowid_t2 = t2.rowid
)

Я не пробовал с индексами, но я думаю, что вы должны иметь один для t2.f1, t2.f2 и t2.f3 для первых трех обновлений (могут потребоваться отдельные индексы с SQLite, не уверен), а другой один в t1.rowid_t2 для двух других обновлений и для t1.rowid_t2 IS NULL.

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

Удачи:)

0 голосов
/ 15 января 2010

Разве это не работает для а)?

update t1,t2
  set t1.rowidt2 = t2.rowid, t1.sts= 1, t2.sts = 1
where t1.f1 = t2.f1 and t1.f2 = t2.f2 and t1.f3 = t2.f3 

и аналогичные с б) и в)?

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