Postgresql Просмотр - производительность с меньшим количеством столбцов - PullRequest
0 голосов
/ 24 апреля 2020

Являются ли представления, у которых меньше столбцов, быстрее, они работают лучше?

В этом примере CREATE VIEW, SELECT имеет только столбцы, в которых проект нуждается немедленно (два из шести столбцов) из таблицы "d").

CREATE VIEW data_with_form_id AS (
SELECT
  e.form_id, d.fld, d.val

Я не хочу быть близоруким; Я мог бы легко добавить мета-столбцы:

CREATE VIEW data_with_form_id AS (
SELECT
  e.form_id, d.*

Но как это влияет на производительность представления?

Я искал "postgresql представление производительности" с несколькими терминами для выберите и столбцы, но просто поиск "postgresql" и "производительности" приводит к такому количеству результатов, что нахождение производительности представления количества столбцов в SELECT - это пропорции иглы в (поле многих) стога сена.

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Определения таблиц + примеры данных:

\i tmp.sql

CREATE table eee
        ( form_id SERIAL NOT NULL PRIMARY KEY
        , payload char (500)
        );

INSERT INTO eee(payload)
SELECT 'payload_'|| gs::text
FROM generate_series(1,100) gs;

CREATE table ddd
        ( id SERIAL NOT NULL PRIMARY KEY
        , form_id SERIAL NOT NULL REFERENCES eee(form_id)
        , fld char (100)
        , val char (200)
        , trash char (400)
        , filth char (800)
        );
CREATE INDEX ON ddd(form_id);


INSERT INTO ddd(form_id, fld,val,trash,filth)
SELECT eee.form_id
        , 'fld_'|| gs::text
        , 'val_'|| gs::text
        , 'trash_'|| gs::text
        , 'filth_'|| gs::text
FROM eee
JOIN generate_series(1,10) gs ON random() < 0.3
        ;

VACUUM ANALYZE eee;
VACUUM ANALYZE ddd;

Два представления:

CREATE VIEW v1 AS
SELECT e.form_id
        , d.fld, d.val
FROM eee e
JOIN ddd d ON d.form_id = e.form_id
        ;

CREATE VIEW v0 AS
SELECT e.payload
        , d.*
FROM eee e
JOIN ddd d ON d.form_id = e.form_id
        ;

Давайте попробуем их:

\echo v1 complete
EXPLAIN SELECT * FROM v1 ;
\echo v1 three fields
EXPLAIN SELECT form_id,fld, val FROM v1 ;

\echo v0 complete
EXPLAIN SELECT * FROM v0 ;
\echo v0 three fields
EXPLAIN SELECT form_id,fld, val FROM v0 ;
\echo v0 four fields
EXPLAIN SELECT form_id,fld, val,trash FROM v0 ;

Вывод:

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 100
CREATE TABLE
CREATE INDEX
INSERT 0 309
VACUUM
VACUUM
CREATE VIEW
CREATE VIEW
v1 complete
                                       QUERY PLAN                                        
-----------------------------------------------------------------------------------------
 Hash Join  (cost=5.09..71.03 rows=309 width=309)
   Hash Cond: (d.form_id = e.form_id)
   ->  Seq Scan on ddd d  (cost=0.00..65.09 rows=309 width=309)
   ->  Hash  (cost=3.84..3.84 rows=100 width=4)
         ->  Index Only Scan using eee_pkey on eee e  (cost=0.14..3.84 rows=100 width=4)
(5 rows)

v1 three fields
                                       QUERY PLAN                                        
-----------------------------------------------------------------------------------------
 Hash Join  (cost=5.09..71.03 rows=309 width=309)
   Hash Cond: (d.form_id = e.form_id)
   ->  Seq Scan on ddd d  (cost=0.00..65.09 rows=309 width=309)
   ->  Hash  (cost=3.84..3.84 rows=100 width=4)
         ->  Index Only Scan using eee_pkey on eee e  (cost=0.14..3.84 rows=100 width=4)
(5 rows)

v0 complete
                             QUERY PLAN                              
---------------------------------------------------------------------
 Hash Join  (cost=9.25..75.18 rows=309 width=2025)
   Hash Cond: (d.form_id = e.form_id)
   ->  Seq Scan on ddd d  (cost=0.00..65.09 rows=309 width=1521)
   ->  Hash  (cost=8.00..8.00 rows=100 width=508)
         ->  Seq Scan on eee e  (cost=0.00..8.00 rows=100 width=508)
(5 rows)

v0 three fields
                                       QUERY PLAN                                        
-----------------------------------------------------------------------------------------
 Hash Join  (cost=5.09..71.03 rows=309 width=309)
   Hash Cond: (d.form_id = e.form_id)
   ->  Seq Scan on ddd d  (cost=0.00..65.09 rows=309 width=309)
   ->  Hash  (cost=3.84..3.84 rows=100 width=4)
         ->  Index Only Scan using eee_pkey on eee e  (cost=0.14..3.84 rows=100 width=4)
(5 rows)

v0 four fields
                                       QUERY PLAN                                        
-----------------------------------------------------------------------------------------
 Hash Join  (cost=5.09..71.03 rows=309 width=713)
   Hash Cond: (d.form_id = e.form_id)
   ->  Seq Scan on ddd d  (cost=0.00..65.09 rows=309 width=713)
   ->  Hash  (cost=3.84..3.84 rows=100 width=4)
         ->  Index Only Scan using eee_pkey on eee e  (cost=0.14..3.84 rows=100 width=4)
(5 rows)

Теперь посмотрим на столбцы «ширины» в планах: они различаются в зависимости не только от определений таблицы и представления, но также от окончательного запроса .

Это потому, что в postgres представление является своего рода макросом : оно объединяется с планом запроса ** до * любой оптимизации. Оптимизатор позже удаляет несвязанные столбцы из плана, что приводит к уменьшенному размеру строки для результата.

Объем данных чтение из базовых таблиц, конечно, тот же: физический таблицы не изменили свои размеры строк.

Примечание для неинсайдеров: я специально использовал CHAR(xxx) столбцы для раздувания размеров строк. varchar() колонны были бы поджарены. (: = поместить во вторичное хранилище), и НЕ будет раздувать размеры строк.

1 голос
/ 24 апреля 2020

Конечно, стоит выбрать столбцы, которые вам не нужны, хотя эта стоимость часто ничтожна. Но выборка столбцов зависит от запроса, использующего представление, а не от определения представления.

Однако добавить новые столбцы к представлению не сложно.

Чтобы увеличить стоимость выборка столбцов, выборка 40-го столбца обходится дороже, чем выборка второго. Извлечение негабаритного столбца, который хранится вне строки в таблице TOAST, особенно затратно.

...