匹配两个大的SQLITE3表

时间:2010-01-14 19:46:15

标签: sql sqlite

我有两张桌子:

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

t2: f1, f2, f3, f4, sts

不同数量的记录超过1000万。

我需要使用每个表的f1f2f3作为键来匹配它们,关系是一个t1的记录可以与一个记录匹配在t2中,或者t1的许多记录可以与t2中的一个记录匹配,匹配取决于以下三个操作中指示的条件。


我需要执行下一个匹配操作:

a)如果t1.f1 = t2.f1以及t1.f2 = t2.f2t1.f3 = t2.f3,我必须将t2的rowid更新为t1.rowid_t2并保存匹配的记录中t1.sts=1t2.sts=1

b)如果t1.f1 = t2.f1以及t1.f2 = t2.f2t1.f3 <> t2.f3,我必须将t2的rowid更新为rowid_t2并保存匹配的记录中t1.sts=2t2.sts=2

c)如果t1.f1 = t2.f1t1.f2 <> t2.f2以及t1.f3 <> t2.f3,我必须将T2的rowid更新为rowid_t2并保存{{1} },t1.sts=3在匹配的记录中。


我有两个问题:

  1. 我可以使用t2.sts=3解决问题吗?如果是的话,如果你能告诉我仅针对a)的解决方案,那就太好了。

  2. 我应该创建多少个索引来优化三个操作所需的UPDATE和SELECT?

  3. 非常感谢!!

2 个答案:

答案 0 :(得分:0)

这不适用于a)?

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 

与b)和c)相似?

答案 1 :(得分:0)

我没有使用SQLite的经验,但我试了一下你的问题。

正如您所说,一次更新多个表格是不可能的(solution provided by Tristran仅适用于MySQL据我所知。

首先我更新t1并为每一行设置sts=1(如果只有几行受到影响,添加WHERE - 子句以获取相关行可能更有效),以及所有相关列匹配的rowid_t2t2.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=2sts=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.f1t2.f2t2.f3(可能需要使用{{1}的单独索引},不确定),另一个SQLite用于其他两个更新和t1.rowid_t2

首先尝试使用一些有代表性的测试数据,看看结果是否符合预期并且性能良好。

祝你好运:)