Индексировать вид соединения с Postgresql? - PullRequest
2 голосов
/ 16 января 2012

У меня есть оператор выбора, который делает очень простой запрос из более сложного вида:

У меня довольно простой оператор выбора ....

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

И мойview - это только int и 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, но это похоже на решение проблемы неэффективности с помощью бинтов.view.

Вот профиль выбора:

                                                        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, запрос занимает секунды, а не доли секунды.

1 Ответ

4 голосов
/ 16 января 2012

Представление не помогает с производительностью.Хорошо только упростить вещи, предоставить конкретные права и некоторые такие.Но это не имеет никакого преимущества для производительности запросов.

Вы можете попытаться вырезать посредника (представление) и использовать этот запрос:

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, которая вообще не нужна в вашем сценарии.(За исключением случаев, когда может отсутствовать соединительная строка для пользователя, что не должно быть возможно.)

Для производительности вам нужно будет сделать это материализованное представление , которое является другим зверемв целом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...