2012-01-16 12 views
2

私はもっと複雑なビューから非常に単純なクエリを作るselect文を持っています....私はかなりストレートフォワードselect文を持ってPostgresqlとの結合ビューを索引付けしますか?

SELECT 
      uid 
    FROM userpermissions 
    WHERE 
      uid   = :whoami 
     AND 
      application = :application 
     AND 
      subsystem = :subsystem 
    ; 

そして、私のビューが唯一のint型で、 varcharsではなく、4つのテーブルの結合(本当の問題になる可能性があります)。

     View "public.userpermissions" 
    Column |   Type   | Modifiers | Storage | Description 
-------------+------------------------+-----------+----------+------------- 
uid   | integer    |   | plain | 
gid   | integer    |   | plain | 
sid   | integer    |   | plain | 
name  | character varying(128) |   | extended | 
application | character varying(128) |   | extended | 
subsystem | character varying(128) |   | extended | 
View definition: 
SELECT users.uid, groups.gid, groupaccess.sid, groups.name, subsystems.application, subsystems.subsystem 
    FROM users 
    JOIN groups ON groups.gid = users.gid 
    JOIN groupaccess ON groups.gid = groupaccess.gid 
    JOIN subsystems ON subsystems.sid = groupaccess.sid; 

は、私は私のクエリは、より効果的であるように、彼らは今、約1〜4秒を取っているとして効果的に、ビューを更新するかどうかはわからないよ、といくつかのケースでは、最大8

私の他の考えは、memcacheを使用することでしたが、それは非効率的な問題の問題に対するバンドエイドソリューションのように感じます。私はPHPのクエリでPDOに入れた瞬間は、秒、第二のない画分がかかるため、完全に私をバッフル

             QUERY PLAN 
---------------------------------------------------------------------------------------------------------------------------- 
Nested Loop (cost=1.18..4.54 rows=1 width=4) (actual time=0.043..0.043 rows=0 loops=1) 
    Join Filter: (groups.gid = users.gid) 
    -> Nested Loop (cost=1.18..3.34 rows=1 width=8) (actual time=0.040..0.040 rows=0 loops=1) 
     -> Hash Join (cost=1.18..2.78 rows=1 width=4) (actual time=0.039..0.039 rows=0 loops=1) 
       Hash Cond: (groupaccess.sid = subsystems.sid) 
       -> Seq Scan on groupaccess (cost=0.00..1.43 rows=43 width=8) (actual time=0.014..0.014 rows=1 loops=1) 
       -> Hash (cost=1.17..1.17 rows=1 width=4) (actual time=0.017..0.017 rows=0 loops=1) 
        Buckets: 1024 Batches: 1 Memory Usage: 0kB 
        -> Seq Scan on subsystems (cost=0.00..1.17 rows=1 width=4) (actual time=0.015..0.015 rows=0 loops=1) 
          Filter: (((application)::text = 'LoginLink'::text) AND ((subsystem)::text = '1'::text)) 
     -> Index Scan using groups_pkey on groups (cost=0.00..0.55 rows=1 width=4) (never executed) 
       Index Cond: (gid = groupaccess.gid) 
    -> Seq Scan on users (cost=0.00..1.19 rows=1 width=8) (never executed) 
     Filter: (uid = 2) 
Total runtime: 0.192 ms 
(15 rows) 

は、ここで選択したのプロファイルです。

+0

pg_queryを使用するとどのくらいの時間がかかりますか?そして、あなたのデータベースサーバーはどこまでありますか? – doctore

+0

DBとWebは同じマシンです。上記のコマンドラインのpsqlは0.192msを示し、PHPから呼び出すと3.6 *秒*を示します。 – Incognito

+0

0.192 msデータベースサーバの時間ですが、PDO関数のPHPインスタンスのpg_query関数を使用すると、どれくらいかかりますか? – doctore

答えて

2

ビューはパフォーマンスには役立ちません。物事を簡素化し、特定の権利を付与し、そのようなものを付与することは、良いことです。しかし、クエリのパフォーマンスには利点はありません。

あなたは仲介人(ビュー)を切り出し、このクエリを使用するように試みることができる。また、中には全く必要とされていない別の中間の男、テーブルgroupsを、切り取る

SELECT u.uid 
FROM users u 
JOIN groupaccess g USING (gid) 
JOIN subsystems s USING (sid) 
WHERE u.uid = :whoami 
    AND s.application = :application 
    AND s.subsystem = :subsystem; 

あなたのシナリオ(ユーザーの接続行が欠落している可能性はありません。

パフォーマンスを向上させるには、別の獣であるmaterialized viewを作成する必要があります。

関連する問題