0

我有一个这种格式的大表(20,000,000+ 行):

id ref  feature val
1  a    pos     pc
2  a    gen     m
3  a    syll    Cv
4  b    pos     pc
5  b    L5      harry
6  c    syll    Cv
7  d    gen     m

如何选择满足多对特征 + val 的参考列表?

例如Select distinct ref where feature='pos' and val = 'pc',给出 a,b Select distinct ref where feature = 'gen' and val= 'm'给出 a,d

但是我如何返回组合的 refs a、b 和 d,对于那些 refsfeature='pos' and val = 'pc'与那些 refs 有的​​那些 refs feature = 'gen' and val= 'm'

我需要能够在同一个搜索中将解决方案扩展到许多这样的对。

搜索需要快速,因此有关索引的建议也会有所帮助。

我应该从同一张表中选择 N 次,每个 feature+val 对一个吗?如果是这样,怎么办?

4

3 回答 3

1

您可以使用“或”选择类似的组合:

Select distinct ref 
from table
where ( feature='pos' and val = 'pc')
  or ( feature = 'gen' and val= 'm' )

如果这会变得太笨拙,您可能希望将您的功能/验证组合移动到另一个表中并对其进行连接。

如果您有一个名为 join_table 的连接表(现在有一个灵感名称!),其中包含 feature 和 val 列,您可以执行以下操作:

select distinct ref
from table t
  inner join join_table j on t.feature = j.feature and t.val = j.val
于 2012-06-26T06:19:33.290 回答
0

通常,您会使用OR语句来添加这些附加子句

  SELECT DISTINCT ref
  FROM   YourTable
  WHERE  (feature = 'pos' AND val = 'pc')
         OR (feature = 'gen' AND val = 'm')
         ...

您可以 通过在连接和时使用持久计算列来简化这一点。featureval

  SELECT DISTINCT ref
  FROM   YourTable
  WHERE  (featureval = 'pospc')
         OR (featureval = 'genm')

但是OR语句的链接仍然存在。

索引

必须通过查看执行计划来评估每个语句的性能,但是对于给定的语句,覆盖索引(feature, val, ref)不会受到伤害。

于 2012-06-26T06:20:10.583 回答
0
sqlite> CREATE TABLE t (id INT, ref VARCHAR, feature VARCHAR, val VARCHAR);
sqlite> 
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (1,  "a",    "pos",     "pc");
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (2,  "a",    "gen",     "m");
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (3,  "a",    "syll",    "Cv");
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (4,  "b",    "pos",     "pc");
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (5,  "b",    "L5",      "harry");
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (6,  "c",    "syll",    "Cv");
sqlite> INSERT INTO t (id, ref, feature, val) VALUES (7,  "d",    "gen",     "m");
sqlite> 
sqlite> SELECT DISTINCT ref FROM t WHERE (feature = 'pos' AND val = 'pc') OR (feature = 'gen' and val= 'm');
a
b
d
sqlite> 

运行时间应该是线性的,2000 万行可能看起来很大,但对于当今的硬件和大多数实现来说这应该不是什么大问题,对过滤器类型进行索引可能会提高性能,确保你的行是固定宽度也可能有轻微的改进。

如果您需要更多配置,只需使用ORwell 添加它们,您就会明白,我建议对其进行测试,并查看查询需要多长时间,我严重怀疑它会很长,尽管我不知道系统也不知道您的实现正在使用,所以我真的不能说太多。

于 2012-06-26T06:22:02.387 回答