在索引列

时间:2016-08-10 20:14:07

标签: postgresql database-design

我有一个大表(+ - 100万行,包括主键的7列)。该表包含两列(即:symbol_01symbol_02),它们被索引并用于查询。此表包含以下行:

id    symbol_01    symbol_02   value_01  value_02
1     aaa          bbb         12        15
2     bbb          aaa         12        15
3     ccc          ddd         20        50
4     ddd          ccc         20        50

根据示例,第1行和第2行是相同的,只是交换了symbol_01symbol_02,但它们对value_01value_02具有相同的值。对于第3行和第4行再次成立。对于整个表格就是这种情况,symbol_01 + symbol_02的每个组合基本上有两行。

我需要找出一种更好的处理方法来摆脱重复。到目前为止,我正在考虑的解决方案是只有一个名为symbol的列,它将是两个符号的组合,因此表格如下:

id    symbol       value_01   value_02
1     ,aaa,bbb,    12         15
2     ,ccc,ddd,    20         50

这会将行数减少一半。另外,symbol列中的每个值都是唯一的。总是需要查询结果以使用两个符号,所以我会这样做:

select value_01, value_02
from my_table
where symbol like '%,aaa,%' and symbol like '%,bbb,%'

这可行,但我的问题是关于表现。这仍然是一张大桌子(很快就会变大)。所以我的问题是,这是针对此方案的最佳解决方案,因为symbol将被编入索引,每个symbol组合将是唯一的,我将需要使用LIKE来查询结果。

有更好的方法吗?我不确定LIKE对于表现有多棒,但我没有看到替代方案?

2 个答案:

答案 0 :(得分:2)

没有高性能解决方案,因为您的问题是将多个值组合到一列中。

创建一个子表(带有当前/主表的外键)到单独保存要搜索的所有单个值,索引该列,查询将很简单快。

答案 1 :(得分:1)

使用此索引:

create index symbol_index on t (
    least(symbol_01, symbol_02),
    greatest(symbol_01, symbol_02)
)

查询将是:

select *
from t
where 
    least(symbol_01, symbol_02) = least('aaa', 'bbb')
    and
    greatest(symbol_01, symbol_02) = greatest('aaa', 'bbb')

或者只是删除重复项:

delete from t
using (
    select distinct on (
        greatest(symbol_01, symbol_02),
        least(symbol_01, symbol_02),
        value_01, value_02
    ) id
    from t
    order by
        greatest(symbol_01, symbol_02),
        least(symbol_01, symbol_02),
        value_01, value_02
) s
where id = s.id

根据列语义,最好按照@Bohemian

的建议对表进行规范化