質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

2746閲覧

経路列挙モデルにておいて、各ノードと、その子孫となる末端ノードを紐付けたい

gittib_gittib

総合スコア102

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

1グッド

2クリップ

投稿2016/01/08 04:41

今、経路列挙モデルでツリー構造を管理しているテーブルがあるのですが、この各ノードに対して、それに紐づく末端のノードを取得する方法を考えています。
一応、末端の子孫ノードは抽出できているものの、時間がかかりすぎるので効率化したいのですが、お知恵を貸していただけないでしょうか。

モデルのイメージは以下の様な感じです。

SQL

1-- 経路列挙モデルを採用しているテーブル 2select node_id, node_path from t_node 3 4 node_id | node_path 5---------+----------- 6 1 | 1 7 2 | 2 8 3 | 1-3 9 4 | 1-3-4 10 5 | 2-5 11 6 | 2-5-6 12 7 | 2-5-6-7 13 8 | 2-8 14 9 | 1-3-9 15 10 | 1-3-9-10 16 17-- view_last_node は末端ノードを抽出するビューです 18select node_id, node_path from view_last_node 19 20 node_id | node_path 21---------+----------- 22 4 | 1-3-4 23 7 | 2-5-6-7 24 8 | 2-8 25 10 | 1-3-9-10 26

ここで今、以下の様なSQLで紐づくノードを抽出しています。マテリアライズド・ビューとしているのですが、現状1万5千レコードほどでもリフレッシュに1分以上かかっています。
node_idはプライマリキーで、node_pathにもインデックスは貼っています。

SQL

1select 2 tn.node_id, 3 tn.node_path, 4 tlast.node_id as last_node, 5 tlast.node_path as last_path 6from t_node as tn 7inner join t_node as tlast on(tlast.node_path like tn.node_path || '%') 8where tlast.node_id in( 9 select node_id from view_last_node 10); 11 12 node_id | node_path | last_node | last_path 13---------+-----------+-----------+------------- 14 1 | 1 | 4 | 1-3-4 15 1 | 1 | 10 | 1-3-9-10 16 2 | 2 | 7 | 2-5-6-7 17 2 | 2 | 8 | 2-8 18 3 | 1-3 | 4 | 1-3-4 19 3 | 1-3 | 10 | 1-3-9-10 20 4 | 1-3-4 | 4 | 1-3-4 21 5 | 2-5 | 7 | 2-5-6-7 22 6 | 2-5-6 | 7 | 2-5-6-7 23 7 | 2-5-6-7 | 7 | 2-5-6-7 24 8 | 2-8 | 8 | 2-8 25 9 | 1-3-9 | 10 | 1-3-9-10 26 10 | 1-3-9-10 | 10 | 1-3-9-10

ちょっとした事でも構いませんので、何かアドバイスいただければと思います。
よろしくお願い致します。m(_ _)m

sho_cs👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

sql

1select 2 tn.node_id 3 , tn.node_path 4 , tlast.node_id as last_node 5 , tlast.node_path as last_path 6from 7 t_node as tn 8 inner join view_last_node as tlast 9 on (tlast.node_path like tn.node_path || '%');

これで少しは早くなるかもしれません。

後は実行計画を見て遅くなっている原因を探しましょう。
また、likeでインデックスを使うにはロケールが関係しているので確認してみてください。
テキスト検索の方法とインデックス — Let's Postgres

投稿2016/01/08 06:20

sho_cs

総合スコア3541

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gittib_gittib

2016/01/08 09:59

回答ありがとうございます。 わずかに速くなりましたが、やはり1%程です。 like検索ですが、explainで確認する限り、インデックスはちゃんと使われていると思います。
guest

0

自己解決

Fettile Forest モデルという、素晴らしいモデルを見つけたので、そちらを共有して自己解決とさせていただきます。
実際に検証はしていませんが、この方法ならば副問い合わせのSQLたった1文で末端ノードを検出できます。

投稿2017/07/12 10:40

gittib_gittib

総合スコア102

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

view_last_node も、マテリアライズドビューでしょうか??

投稿2016/01/08 05:08

Toyoshima

総合スコア422

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gittib_gittib

2016/01/08 06:58

view_last_node は通常のビューですが、SQL全体からすると1%にも満たない程度のコストしか掛かっていないため、マテリアライズド・ビューにしてもほとんど改善は見込めないと思っています。 回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問