web-dev-qa-db-fra.com

Actualiser l'impact de la vue matérialisée sur la DB

Bonjour, nous exécutons une base de données PostgreSQL 9.6 dans Amazon RDS sous A M4.Large (2CPU 8 Go) et un IOPS provisionné de 1000. Le cas d'utilisation est le suivant: Nous avons une table avec plusieurs millions de registres (4M de plus ou moins) et Nous avons créé une vue matérialisée avec un sous-ensemble de ce tableau (2M APROX) modifiant certaines colonnes types pour être plus efficace en interrogation. Notre PG_CONF n'a pas été modifié, en train d'être par défaut de RDS Postgres.

Ceci est notre définition de vue:

CREATE MATERIALIZED VIEW public.customers_mv as
SELECT 
    id,
    gender,
    contact_info,
    location,
    social,
    categories,
    (social ->> 'follower_count')::integer AS social_follower_count,
    (social ->> 'following_count')::integer AS social_following_count,
    (social ->> 'peemv')::float AS social_emv,
    (social ->> 'engagement')::float AS social_engagement,
    (social ->> 'v')::boolean AS social_validated,
    search_vector,
    flags,
    to_tsvector('english',concat_ws(' ','aal0_'||(customers.location ->> 'aal0'),
      'aal1_'||(customers.location ->> 'aal1'),
      'aal2_'||(customers.location ->> 'aal2'),
      'frequent_location_aal0_'||(customers.location -> 'frequent_location' ->> 'aal0'),
      'frequent_location_aal1_'||(customers.location -> 'frequent_location' ->> 'aal1'),
      'frequent_location_aal2_'||(customers.location -> 'frequent_location' ->> 'aal2'),
      'last_post_location_aal0_'||(customers.location -> 'last_post_location' ->> 'aal0'),
      'last_post_location_aal1_'||(customers.location -> 'last_post_location' ->> 'aal1'),
      'last_post_location_aal2_'||(customers.location -> 'last_post_location' ->> 'aal2'),
      'admin_location_aal0_'||(customers.location -> 'admin_location' ->> 'aal0'),
      'bio_location_aal0_'||(customers.location -> 'bio_location' ->> 'aal0'))) as loc_vector
FROM public.customers
WHERE (customers.social -> 'follower_count') > '5000'
AND customers.social ? 'last_posts' 
AND (customers.flags IS NULL OR NOT customers.flags @> '{"destroy": true}'::jsonb);


CREATE INDEX customers_mv_followerc_idx ON customers_mv USING BTREE (social_follower_count);
CREATE INDEX customers_mv_folling_idx ON customers_mv USING BTREE (social_following_count);
CREATE INDEX customers_mv_emv_idx ON customers_mv USING BTREE (social_emv);
CREATE INDEX customers_mv_gin_social_idx ON customers_mv USING GIN (social jsonb_path_ops);
CREATE INDEX customers_mv_partial_social_validated_idx ON customers_mv (social_validated) WHERE social_validated = FALSE;
CREATE INDEX customers_mv_categories_idx ON customers_mv USING gin (categories);
CREATE INDEX customers_mv_gin_location_idx ON customers_mv USING GIN (location jsonb_path_ops);
CREATE INDEX customers_mv_gin_loc_vector ON customers_mv USING gin(loc_vector);
CREATE UNIQUE INDEX customers_mv_uniq_id_idx ON customers_mv (id);

Notre point de vue a quelques colonnes uniquement pour accéder à des données telles que location ou social (type JSONB) et d'autres similaires loc_vector Pour avoir interrogé plus rapidement.

Maintenant le problème: Le problème survient lorsque nous essayons d'actualiser, d'actualiser simultanément ou de créer une nouvelle vue matérialisée, lorsque nous essayons de lancer la commande de rafraîchissement de la CPU. ou les iops d'écriture écrasent le dB.

Ici, nous pouvons être à quel point il frappe le DB CPU Usage

enter image description here

Quel serait le cadre idéal compte tenu de nos exigences?

C'est un problème d'augmentation des infrastructures ou peut-être une question de configuration/optimisation?

6
Imanol Y.

Votre problème est probablement les index.

IIRC, rafraîchissant une vue matérialisée goutte aux données existantes et crée une nouvelle "table" avec les données actuelles.

Ce que cela fait pour vos index est ré-indexer l'ensemble du sous-ensemble de données, qui basé sur vos index envoient comme une charge de travail significative.

Ma recommandation ne serait pas d'utiliser les vues matérialisées intégrées et de faire valoir votre propre équivalent, de mettre à jour progressivement des données, de sorte que vous n'écrivez que des données/index stables.

Le compromis est que cela sera beaucoup plus complexe à construire que de simplement créer une vue matérialisée, et vous devrez déterminer comment vous souhaitez suivre l'invalidation des données stables.

1
jlovison