O (log n)
時間内にクエリのインデックス作成と実行に問題があります。
クエリには、_INNER JOIN
_、_ORDER BY
_、および等価演算が含まれます。データベースの法則を正しく理解している場合、非等値演算子が複数の列で使用されていなければ、クエリにインデックスを付けてO (log n)
時間(またはその前後)で実行できます。この場合、_INNER JOIN
_は等価演算子としてカウントされ、非等価演算子はクエリの_ORDER BY
_部分になると思います。このテーブルには10,000,000以上の行があり、1秒あたり数回の読み取りと書き込みを処理する必要があります。
PostgreSQLの使用。これはテーブルがどのように見えるかです。ご覧のとおり、「Names」列はリストプロパティであり、_INNER JOIN
_が対象とする列です。
_Age Names Date
34 ['carla', 'john', 'sam'] 3/13/2011
26 ['json', 'cindy', 'joel'] 3/13/2011
72 ['beth', 'amber', 'susie'] 3/13/2011
14 ['john', 'jim', 'debie'] 3/13/2011
_
これは私たちがやろうとしているクエリです:
_SELECT * FROM the_table WHERE Age==26 AND Names=='john' ORDER BY Date
_
私の背景はApp Engineのビッグテーブルを使用しているため、ここでは等号演算子を使用して_'john'
_をNames
列の名前の1つにする必要があることを示しています。これは、GAEのビッグテーブルでは許容可能なクエリです。すべてのビッグテーブルクエリが実行する必要があるため、O (log N)
時間で実行されます。 PostgreSQLはリストデータ型を列として受け入れるため、PostgreSQLでもこれを行う方法があると想定しています。
これはPostgreSQLで可能ですか?
もしそうなら、どのようにインデックスを設定する必要がありますか(3つのプロパティを考慮に入れてインデックスを設定する方法を理解できません)?
これは、PostgreSQL 8.4以降で可能です。複数列のGINインデックスを作成するには、追加モジュール btree_gin をインストールする必要があります。
通常、integer
やdate
のような単純なタイプは、(デフォルトの)Bツリーインデックスを使用する方がよいため、標準のPostgreSQLにはインストールされません。ただし、このようなケースでは、複数列のインデックスが最も高速であるため、プレーンタイプには追加のインデックスメソッドが必要です。
PostgreSQL 9.1以降では CREATE EXTENSION
:
CREATE EXTENSION btree_gin;
古いバージョン 特権システムユーザー(postgresなど)として実行します。
psql -d dbname -f SHAREDIR/contrib/btree_gin.sql
DebianのPostgreSQL 8.4インストールの場合、これは次のようになります。
psql -d mydb -f /usr/share/postgresql/8.4/contrib/btree_gin.sql
次に、このテーブルを与えます:
CREATE TEMP TABLE tbl (age int, names text[], thedate date);
...この複数列のGINインデックスを作成できます。
CREATE INDEX tbl_gin_idx ON tbl USING GIN (names, age, thedate);
...次のようなクエリで使用できます。
SELECT * FROM tbl
WHERE age = 26
AND '{json}'::text[] <@ names
ORDER BY thedate;
注GINインデックスは、書き込み操作に重要なコストをもたらすことに注意してください。
しかし、インデックスのない1000万行のSELECT
があなたに何をするかと比較すると、それは言及する価値がほとんどありません。
あなたは試してみましたか:
SELECT * from the_table WHERE Age = 26 AND array['john'] && Names ORDER BY Date
次のようなインデックスを使用する:
CREATE INDEX the_table_idx ON the_table USING GIN (Names, Age, Date);
または少なくとも次のようなインデックス
CREATE INDEX the_table_idx ON the_table USING GIN (Names, Age);