2

私はこのようなテーブルを持っていますedge

-------------------------------
| id | arg1 | relation | arg2 |
-------------------------------
| 1  |   1  |     3    |   4  |
-------------------------------
| 2  |   2  |     6    |   5  |
-------------------------------

ここで、arg1、relation、およびarg2は、別のobjectテーブル内のオブジェクトのIDを参照します。

--------------------
| id | object_name |
--------------------
| 1  |   book      |
--------------------
| 2  |   pen       |
--------------------
| 3  |   on        |
--------------------
| 4  |   table     |
--------------------
| 5  |   bag       |
--------------------
| 6  |   in        |
--------------------

私がやりたいのは、パフォーマンスの問題(5000万を超えるエントリの非常に大きなテーブル)を考慮して、次のようなものobject_nameではなく、各エッジエントリのを表示することです。id

---------------------------
| arg1 | relation | arg2  |
---------------------------
| book |    on    | table |
---------------------------
|  pen |    in    | bag   |
---------------------------

これを行うための最良の選択クエリは何ですか?また、クエリを最適化するための提案を受け入れています-テーブルにインデックスを追加するなど...

編集:以下のコメントに基づく:

1)@Craig Ringer:両方のテーブルのPostgreSQL version: 8.4.13インデックスのみです。id

2)@andrefsp:edgeは。のほぼx2倍ですobject

4

2 に答える 2

2

データベースの構造を変更できる場合は、データベースのこの部分を非正規化し、フィールドidarg1_namerelation_namearg2_nameを使用してテーブルエッジを作成することができます。また、テーブルオブジェクトを変更せずに保持して、挿入または更新するときにエッジテーブルの名前を取得します。

良くない。データが重複し(データベースのサイズが大きくなります)、テーブルの挿入または更新が困難になる場合があります。

ただし、選択は高速である必要があります(JOINなし)。

SELECT arg1_name, relation_name, arg2_name
FROM edge;
于 2012-11-24T18:13:22.340 に答える
0

これより安くなることはありません:

SELECT o1.object_name, r1.object_name, o2.object_name
FROM   edge e
JOIN   object o1 ON o1.id = e.arg1
JOIN   object  r ON  r.id = e.relation
JOIN   object o2 ON o2.id = e.arg2;

そして、これ以上のインデックスは必要ありません。object.idこのクエリに必要なのは1つだけです 。

しかし、私はあなたが一度に5000万行を特定の順序で取得したいとは思っていないことを真剣に疑っています。あなたはまだ全体像を示していませんでした。

于 2012-11-24T00:23:09.017 に答える