2012-01-16 47 views
2

我有一個select語句,使一個非常簡單的查詢從一個更復雜的看法:索引與Postgresql連接的視圖?

我有一個相當直接的select語句....

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

而我的觀點是唯一的整數和varchars,但加入了四張表(可能是真正的問題)。

     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,但這對於低效率的問題就像是一個創可貼的解決方案。

這裏的選擇的一個配置文件:

             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) 

這完全令我感到困惑,因爲我把它改成PDO與PHP查詢此刻只需幾秒鐘,一秒鐘的不是分數。

+0

使用pg_query需要多長時間?而且,你的數據庫服務器有多遠? – doctore 2012-01-16 16:16:26

+0

DB和Web是同一臺機器。上面的命令行psql指示0.192ms,當從PHP調用時指示3.6 *秒*。 – Incognito 2012-01-16 16:18:32

+0

0.192 ms這是數據庫服務器中的時間,但是如果使用PDO函數的PHP實例的函數pg_query,需要多長時間? – doctore 2012-01-16 16:30:57

回答

2

視圖對性能沒有幫助。只是簡化事情,授予特定的權利等等。但它對查詢性能沒有好處。

你可以嘗試削減了中間人(視圖),並使用此查詢:

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; 

這也削減了另一箇中間人,表groups,這是沒有必要的在你的場景。 (除非用戶的連接行可能丟失,這是不可能的。)

爲了提高性能,您必須完成一個materialized view,這是一個完全不同的野獸。