Analyse des tables - Amazon Redshift

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Analyse des tables

L'ANALYZEopération met à jour les métadonnées statistiques que le planificateur de requêtes utilise pour choisir les plans optimaux.

Dans la plupart des cas, il n'est pas nécessaire d'exécuter explicitement la ANALYZE commande. Amazon Redshift surveille les modifications apportées à votre application et met à jour automatiquement les statistiques en arrière-plan. En outre, la COPY commande effectue une analyse automatiquement lorsqu'elle charge des données dans une table vide.

Pour analyser explicitement une table ou la base de données complète, exécutez la commande ANALYZE.

Analyse automatique

Amazon Redshift surveille en permanence votre base de données et effectue automatiquement des opérations d’analyse en arrière-plan. Pour réduire au maximum l’impact sur vos performances système, l’analyse automatique s’exécute pendant les périodes où les charges de travail sont légères.

L’analyse automatique est activée par défaut. Pour désactiver l’analyse automatique, attribuez au paramètre auto_analyze la valeur false en modifiant le groupe de paramètres de votre cluster.

Pour réduire le temps de traitement et améliorer les performances globales du système, Amazon Redshift ignore l’analyse automatique pour toute table dont l’ampleur des modifications est petite.

Une opération d'analyse ignore les tables contenant des up-to-date statistiques. Si vous l'exécutez dans ANALYZE le cadre de votre flux de travail d'extraction, de transformation et de chargement (ETL), l'analyse automatique ignore les tables contenant des statistiques actuelles. De même, un utilisateur explicite ANALYZE ignore les tables lorsque l'analyse automatique a mis à jour les statistiques de la table.

Analyse des données des nouvelles tables

Par défaut, la COPY commande exécute une ANALYZE fois les données chargées dans une table vide. Vous pouvez forcer une table, qu'elle ANALYZE soit vide ou non, en activant STATUPDATE la valeur ON. Si vous le spécifiez STATUPDATEOFF, aucun n'ANALYZEest effectué. Seul le propriétaire de la table ou un superutilisateur peut exécuter la ANALYZE commande ou exécuter la COPY commande avec la valeur ON STATUPDATE définie sur ON.

Amazon Redshift analyse également les nouvelles tables que vous créez avec les commandes suivantes :

  • CREATETABLEEN TANT QUE (CTAS)

  • CREATETEMPTABLEEN TANT QUE

  • SELECT INTO

Amazon Redshift renvoie un message d’avertissement lorsque vous exécutez une requête sur une nouvelle table qui n’a pas été analysée après le chargement initial de ses données. Aucun avertissement n’est fourni lorsque vous interrogez une table après un chargement ou une mise à jour ultérieur(e). Le même message d'avertissement est renvoyé lorsque vous exécutez la EXPLAIN commande sur une requête qui fait référence à des tables qui n'ont pas été analysées.

Chaque fois qu’un ajout de données à une table non vide modifie de façon importante la taille de la table, vous pouvez mettre à jour explicitement les statistiques. Pour ce faire, exécutez une ANALYZE commande ou utilisez l'option STATUPDATE ON avec la COPY commande. Pour afficher des informations détaillées sur le nombre de lignes qui ont été insérées ou supprimées depuis la dernièreANALYZE, interrogez la table du catalogue du PG_STATISTIC_INDICATOR système.

Vous pouvez définir la portée de la commande ANALYZE en spécifiant l’une des valeurs suivantes :

  • La totalité de la base de données actuelle

  • Une seule table

  • Une ou plusieurs colonnes spécifiques d’une seule table

  • Colonnes qui sont susceptibles d’être utilisées comme prédicats dans des requêtes

La ANALYZE commande extrait un échantillon de lignes de la table, effectue des calculs et enregistre les statistiques de colonne qui en résultent. Par défaut, Amazon Redshift exécute une passe d'échantillonnage pour la DISTKEY colonne et une autre passe d'échantillonnage pour toutes les autres colonnes de la table. Si vous souhaitez générer des statistiques pour un sous-ensemble de colonnes, vous pouvez spécifier une liste de colonnes séparées par des virgules. Vous pouvez exécuter ANALYZE la PREDICATE COLUMNS clause pour ignorer les colonnes qui ne sont pas utilisées comme prédicats.

ANALYZEles opérations étant gourmandes en ressources, exécutez-les uniquement sur des tables et des colonnes qui nécessitent réellement des mises à jour de statistiques. Vous n’avez pas besoin d’analyser toutes les colonnes de toutes les tables régulièrement ou selon le même calendrier. Si les données changent considérablement, analysez les colonnes qui sont fréquemment utilisées dans les cas suivants :

  • Tri et regroupement d’opérations

  • Jointures

  • Prédicats de requête

Pour réduire le temps de traitement et améliorer les performances globales du système, Amazon Redshift ignore ANALYZE les tables contenant un faible pourcentage de lignes modifiées, tel que déterminé par le paramètre. analyze_threshold_percent Par défaut, le seuil d’analyse est défini sur 10 %. Vous pouvez modifier le seuil d’analyse pour la séance en cours en exécutant une commande SET.

Les colonnes les moins susceptibles de nécessiter une analyse fréquente sont celles qui représentent des faits et des mesures, ainsi que les attributs connexes qui ne sont jamais réellement interrogés, tels que les grandes VARCHAR colonnes. Par exemple, considérez la LISTING table de la TICKIT base de données.

select "column", type, encoding, distkey, sortkey from pg_table_def where tablename = 'listing'; column | type | encoding | distkey | sortkey ---------------+--------------------+----------+---------+--------- listid | integer | none | t | 1 sellerid | integer | none | f | 0 eventid | integer | mostly16 | f | 0 dateid | smallint | none | f | 0 numtickets | smallint | mostly8 | f | 0 priceperticket | numeric(8,2) | bytedict | f | 0 totalprice | numeric(8,2) | mostly32 | f | 0 listtime | timestamp with... | none | f | 0

Si cette table est chargée chaque jour avec un grand nombre de nouveaux enregistrements, la LISTID colonne, fréquemment utilisée dans les requêtes comme clé de jointure, doit être analysée régulièrement. Si TOTALPRICE les contraintes LISTTIME sont fréquemment utilisées dans les requêtes, vous pouvez analyser ces colonnes et la clé de distribution tous les jours de la semaine.

analyze listing(listid, totalprice, listtime);

Supposons que les vendeurs et les événements de l'application soient beaucoup plus statiques et que la date IDs fasse référence à un ensemble de jours fixes couvrant seulement deux ou trois ans. Dans ce cas, les valeurs uniques de ces colonnes ne changent pas de façon significative. Cependant, le nombre d’instances de chaque valeur unique augmente de façon continue.

En outre, considérez le cas où les PRICEPERTICKET mesures NUMTICKETS et sont rarement demandées par rapport à la colonne. TOTALPRICE Dans ce cas, vous pouvez exécuter la ANALYZE commande sur l'ensemble du tableau une fois par week-end pour mettre à jour les statistiques des cinq colonnes qui ne sont pas analysées quotidiennement :

Colonnes de prédicat

Comme solution pratique autre que spécifier une liste de colonnes, vous pouvez choisir d’analyser uniquement les colonnes susceptibles d’être utilisées comme prédicats. Quand vous exécutez une requête, les colonnes qui sont utilisées dans une jointure, une condition de filtre ou une clause group by sont marquées en tant que comme colonnes de prédicat dans le catalogue système. Lorsque vous exécutez ANALYZE la PREDICATE COLUMNS clause, l'opération d'analyse inclut uniquement les colonnes répondant aux critères suivants :

  • La colonne est marquée en tant que colonne de prédicat.

  • La colonne est une clé de distribution.

  • La colonne fait partie d’une clé de tri.

Si aucune des colonnes d'une table n'est marquée comme prédicat, ANALYZE inclut toutes les colonnes, même si cela PREDICATE COLUMNS est spécifié. Si aucune colonne n’est marquée comme colonne de prédicat, c’est peut-être parce que la table n’a pas encore été interrogée.

Vous pouvez choisir de l'utiliser PREDICATE COLUMNS lorsque le modèle de requête de votre charge de travail est relativement stable. Lorsque le modèle de requête est variable, différentes colonnes étant fréquemment utilisées comme prédicats, son utilisation PREDICATE COLUMNS peut temporairement entraîner des statistiques périmées. Des statistiques obsolètes peuvent donner lieu à des plans d’exécution de requête peu efficaces et à des lenteurs d’exécution. Toutefois, lors de la prochaine ANALYZE utilisation PREDICATECOLUMNS, les nouvelles colonnes de prédicat seront incluses.

Pour afficher les détails des colonnes de prédicat, utilisez ce qui suit SQL pour créer une vue nommée PREDICATE _COLUMNS.

CREATE VIEW predicate_columns AS WITH predicate_column_info as ( SELECT ns.nspname AS schema_name, c.relname AS table_name, a.attnum as col_num, a.attname as col_name, CASE WHEN 10002 = s.stakind1 THEN array_to_string(stavalues1, '||') WHEN 10002 = s.stakind2 THEN array_to_string(stavalues2, '||') WHEN 10002 = s.stakind3 THEN array_to_string(stavalues3, '||') WHEN 10002 = s.stakind4 THEN array_to_string(stavalues4, '||') ELSE NULL::varchar END AS pred_ts FROM pg_statistic s JOIN pg_class c ON c.oid = s.starelid JOIN pg_namespace ns ON c.relnamespace = ns.oid JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = s.staattnum) SELECT schema_name, table_name, col_num, col_name, pred_ts NOT LIKE '2000-01-01%' AS is_predicate, CASE WHEN pred_ts NOT LIKE '2000-01-01%' THEN (split_part(pred_ts, '||',1))::timestamp ELSE NULL::timestamp END as first_predicate_use, CASE WHEN pred_ts NOT LIKE '%||2000-01-01%' THEN (split_part(pred_ts, '||',2))::timestamp ELSE NULL::timestamp END as last_analyze FROM predicate_column_info;

Supposons que vous exécutiez la requête suivante sur la LISTING table. Notez que LISTIDLISTTIME, et EVENTID sont utilisés dans les clauses de jointure, de filtrage et de regroupement par.

select s.buyerid,l.eventid, sum(l.totalprice) from listing l join sales s on l.listid = s.listid where l.listtime > '2008-12-01' group by l.eventid, s.buyerid;

Lorsque vous interrogez la COLUMNS vue PREDICATE _, comme indiqué dans l'exemple suivant, vous voyez cela LISTID et vous LISTTIME êtes marqué comme des colonnes de prédicat. EVENTID

select * from predicate_columns where table_name = 'listing';
schema_name | table_name | col_num | col_name       | is_predicate | first_predicate_use | last_analyze       
------------+------------+---------+----------------+--------------+---------------------+--------------------
public      | listing    |       1 | listid         | true         | 2017-05-05 19:27:59 | 2017-05-03 18:27:41
public      | listing    |       2 | sellerid       | false        |                     | 2017-05-03 18:27:41
public      | listing    |       3 | eventid        | true         | 2017-05-16 20:54:32 | 2017-05-03 18:27:41
public      | listing    |       4 | dateid         | false        |                     | 2017-05-03 18:27:41
public      | listing    |       5 | numtickets     | false        |                     | 2017-05-03 18:27:41
public      | listing    |       6 | priceperticket | false        |                     | 2017-05-03 18:27:41
public      | listing    |       7 | totalprice     | false        |                     | 2017-05-03 18:27:41
public      | listing    |       8 | listtime       | true         | 2017-05-16 20:54:32 | 2017-05-03 18:27:41

Tenir les statistiques à jour améliore les performances des requêtes en permettant au planificateur de requête de choisir les plans optimaux. Amazon Redshift actualise automatiquement les statistiques en arrière-plan, et vous pouvez également exécuter la commande de manière explicite. ANALYZE Si vous choisissez d'exécuter explicitementANALYZE, procédez comme suit :

  • Exécutez la ANALYZE commande avant d'exécuter des requêtes.

  • Exécutez régulièrement la ANALYZE commande sur la base de données à la fin de chaque cycle normal de chargement ou de mise à jour.

  • Exécutez la ANALYZE commande sur toutes les nouvelles tables que vous créez et sur toutes les tables ou colonnes existantes qui subissent des modifications importantes.

  • Envisagez d'exécuter ANALYZE des opérations selon des plannings différents pour différents types de tables et de colonnes, en fonction de leur utilisation dans les requêtes et de leur propension à changer.

  • Pour économiser du temps et des ressources de cluster, utilisez la PREDICATE COLUMNS clause lors de l'exécutionANALYZE.

Il n'est pas nécessaire d'exécuter explicitement la ANALYZE commande après avoir restauré un instantané dans un cluster provisionné ou un espace de noms sans serveur, ni après avoir repris un cluster provisionné suspendu. Amazon Redshift préserve les informations des tables système dans ces cas, ce qui rend ANALYZE les commandes manuelles inutiles. Amazon Redshift continuera à exécuter des opérations d’analyse automatique selon les besoins.

Une opération d'analyse ignore les tables contenant des up-to-date statistiques. Si vous l'exécutez dans ANALYZE le cadre de votre flux de travail d'extraction, de transformation et de chargement (ETL), l'analyse automatique ignore les tables contenant des statistiques actuelles. De même, un utilisateur explicite ANALYZE ignore les tables lorsque l'analyse automatique a mis à jour les statistiques de la table.

ANALYZEhistorique des commandes

Il est utile de savoir quand la dernière ANALYZE commande a été exécutée sur une table ou une base de données. Lorsqu'une ANALYZE commande est exécutée, Amazon Redshift exécute plusieurs requêtes qui ressemblent à ceci :

padb_fetch_sample: select * from table_name

Requête STL _ ANALYZE pour afficher l'historique des opérations d'analyse. Si Amazon Redshift analyse une table à l’aide d’une analyse automatique, la colonne is_background est définie sur t (true). Sinon, elle est définie sur f (false). L'exemple suivant joint STV _ TBL _ PERM pour afficher le nom de la table et les détails de l'exécution.

select distinct a.xid, trim(t.name) as name, a.status, a.rows, a.modified_rows, a.starttime, a.endtime from stl_analyze a join stv_tbl_perm t on t.id=a.table_id where name = 'users' order by starttime; xid | name | status | rows | modified_rows | starttime | endtime -------+-------+-----------------+-------+---------------+---------------------+-------------------- 1582 | users | Full | 49990 | 49990 | 2016-09-22 22:02:23 | 2016-09-22 22:02:28 244287 | users | Full | 24992 | 74988 | 2016-10-04 22:50:58 | 2016-10-04 22:51:01 244712 | users | Full | 49984 | 24992 | 2016-10-04 22:56:07 | 2016-10-04 22:56:07 245071 | users | Skipped | 49984 | 0 | 2016-10-04 22:58:17 | 2016-10-04 22:58:17 245439 | users | Skipped | 49984 | 1982 | 2016-10-04 23:00:13 | 2016-10-04 23:00:13 (5 rows)

Vous pouvez également exécuter une requête plus complexe qui renvoie toutes les instructions exécutées dans chaque transaction terminée incluant une ANALYZE commande :

select xid, to_char(starttime, 'HH24:MM:SS.MS') as starttime, datediff(sec,starttime,endtime ) as secs, substring(text, 1, 40) from svl_statementtext where sequence = 0 and xid in (select xid from svl_statementtext s where s.text like 'padb_fetch_sample%' ) order by xid desc, starttime; xid | starttime | secs | substring -----+--------------+------+------------------------------------------ 1338 | 12:04:28.511 | 4 | Analyze date 1338 | 12:04:28.511 | 1 | padb_fetch_sample: select count(*) from 1338 | 12:04:29.443 | 2 | padb_fetch_sample: select * from date 1338 | 12:04:31.456 | 1 | padb_fetch_sample: select * from date 1337 | 12:04:24.388 | 1 | padb_fetch_sample: select count(*) from 1337 | 12:04:24.388 | 4 | Analyze sales 1337 | 12:04:25.322 | 2 | padb_fetch_sample: select * from sales 1337 | 12:04:27.363 | 1 | padb_fetch_sample: select * from sales ...