2016-08-10 8 views
2

私は大きなテーブルを持っています(1万行、主キーを含む7列)。この表には、2つの列(つまり、symbol_01およびsymbol_02)が含まれており、これらの列は索引付けされ、問合せに使用されます。例えば、行1及び2の通り インデックス付きの列でのLIKEの最適な使用

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 

が交換さsymbol_01symbol_02ことを除いて同一であるが、それらはvalue_01value_02に同じ値を有する:この表は、以下のような行を含みます。これは、行3と4で再び真実です。これは、テーブル全体の場合で、symbol_01 + symbol_02の組み合わせごとに本質的に2つの行があります。

私は重複を取り除くためにこれを処理するより良い方法を見つけ出す必要があります。これまでのところ、私は検討しています解決策はただ一つの列が二つのシンボルの組み合わせになります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パフォーマンスのためのものですが、私は別の方法が表示されませんかわからない?このインデックス付き

答えて

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 

列のセマンティクスに依存して、より良いかもしれません提案されているようにテーブルを正規化します。

2

問題が複数の値を1つの列に集約しているため、高性能のソリューションはありません。

別途に(あなたの現在/メインテーブルへの外部キーで)子テーブルの作成は、インデックス、その列とクエリがシンプル速くなり、あなたが検索したいすべての個々の値を保持します。

関連する問題