L’environnement de développement Dream Data Warehouse

L’environnement de développement Dream Data Warehouse


Plus tôt ce mois-ci, l’équipe d’activation client de Snowflake a reçu un e-mail de l’un de nos clients. Le client a déclaré qu’il n’était pas satisfait de l’idée de cloner des copies complètes des bases de données de production à des fins de développement. « Voulons-nous vraiment développer et maintenir un système pour copier une fraction de la base de données de production vers le développeur ? », Citant la raison de son message selon lequel, en copiant simplement l’intégralité de la base de données de production, l’équipe de développement aurait accès à trop de données . Étant un vétéran de Snowflake, j’ai d’abord rejeté son inquiétude en raison de la capacité de clonage sans copie de Snowflake, comme indiqué dans cet article. De mon point de vue, le clone sans copie n’entraînerait aucun coût supplémentaire à des fins de développement, alors pourquoi ne pas donner à l’équipe de développement toutes les données ?

La réponse, bien sûr, comme l’a souligné le client, consiste à rendre l’effort de développement plus efficace. L’hypothèse d’un clone sans copie équivalant à un développement à coût nul est, bien sûr, incorrecte. Il y a le coût d’interrogation des données (nécessitant des crédits d’entrepôt virtuel) et le coût derrière chaque heure de développement. Après tout, des temps de requête plus longs entraînent des itérations de développement plus longues et des cycles de test plus longs. Pour créer un environnement de développement « heureux » dans Snowflake, nous avons besoin d’une approche plus raffinée pour créer l’ensemble de données de développement.

L’approche décrite par le client était enracinée dans le complément du clone zéro copie de Snowflake avec la technique supplémentaire consistant à utiliser Échantillonnage de bloc. En d’autres termes, ils ont proposé de créer une vue contenant un jeu d’échantillons à partir de la table d’origine. Cette approche permet à un administrateur de configurer rapidement un environnement de développement avec un minimum de données. Contrôler la quantité d’échantillons de données est une bonne chose pour de nombreuses situations de développement, car les développeurs ont rarement besoin d’accéder à l’ensemble de données complet.

Ok, regardons SAMPLE / TABLESAMPLE et voyons comment nous pouvons faire cela. La syntaxe est assez simple :

 
 SELECT ...
 FROM ...
   { SAMPLE | TABLESAMPLE } [ samplingMethod ] ( <probability> ) [ { REPEATABLE | SEED } ( <seed> ) ]
 [ ... ]
 
 -- Where:
    samplingMethod :: = { { BERNOULLI | ROW } | { SYSTEM | BLOCK } }


Notez qu’il existe certains termes interchangeables auxquels nous devons prêter attention lors de l’écriture de la requête. Ces termes sont synonymes et ne diffèrent que par la syntaxe :

SAMPLE | TABLESAMPLE

BERNOULLI | ROW

SYSTEM | BLOCK

REPEATABLE | SEED

Les deux principales méthodes d’échantillonnage sont l’échantillonnage ROW (ou BERNOULLI) et BLOCK (ou SYSTEM). Examinons chacun d’eux de plus près.

Échantillonnage de ligne

Cette approche utilise le principe de Bernoulli pour sélectionner les données en appliquant une probabilité de p/100 à chaque rangée. Dans la documentation de Snowflake, nous mentionnons que cela revient à « lancer une pièce pondérée » sur chaque ligne. Le nombre de lignes échantillonnées (sélectionnées) doit être égal à (p/100) * nn est le nombre total de lignes dans le tableau et p est la valeur de probabilité de l’échantillon définie par l’utilisateur.

Cette méthode implique que nous allons parcourir chaque ligne et calculer une probabilité à chaque ligne pour correspondre à un candidat de ligne. Cette itération va impacter les performances des requêtes. Cependant, l’avantage ici est que nous nous retrouverons avec une distribution formelle et concise d’échantillons de nos données. En ce qui concerne la création d’un environnement de développement, l’utilisation de la méthode d’échantillonnage de Bernoulli pour créer une vue n’entraîne pas de meilleures performances. Cependant, vous pouvez certainement créer une nouvelle table de données basée sur cette méthode d’échantillonnage et numériser encore moins de données. Par exemple:

create table dev_Sales_LineItem_Bernoulli_20 as

    select *

    from SALES.PUBLIC.LINEITEM

    sample bernoulli (20);

Cette instruction créera une table de développement à partir de la table LINEITEM dans notre base de données SALES avec 20 % des lignes de la table d’origine.

Je ne m’attarderai pas trop sur cette méthode dans cet article. Vous pouvez vous sentir libre d’expérimenter par vous-même pour voir si cette méthode d’échantillonnage répond à vos besoins. Au lieu de cela, je parlerai davantage de l’échantillonnage par bloc.

Échantillonnage de bloc

Dans cette approche, nous appliquons une probabilité de p/100 à chaque bloc de lignes. Pour ceux qui connaissent les micropartitions de Snowflake (détails ci-dessous), l’échantillonnage par blocs choisit des partitions individuelles en fonction d’une probabilité spécifique. Si vous souhaitez simplement accéder rapidement aux données de production et exécuter des requêtes sur un petit pourcentage des lignes d’une table, tirer parti de l’échantillonnage par blocs est une bonne solution.

Examinons cela avec un exemple spécifique utilisant la méthode d’échantillonnage de blocs sur la table LINEITEM dans la base de données SALES. Voici les métadonnées de la table :

image4

Dans cet exemple, j’ai un développeur qui travaille sur une requête d’agrégation sur la table LINEITEM. Il a créé une requête simple comme celle-ci :

select

l_returnflag,

l_linestatus,

sum(l_quantity) as sum_qty,

sum(l_extendedprice) as sum_base_price,

sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,

sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,

avg(l_quantity) as avg_qty,

avg(l_extendedprice) as avg_price,

avg(l_discount) as avg_disc,

count(*) as count_order

from

lineitem

where

l_orderdate <= dateadd(day, -90, to_date('1998-12-01'))

group by

l_returnflag,

l_linestatus

order by

l_returnflag,

L_linestatus;

Résultat:

image3

Cette requête rapporte le montant des affaires qui ont été facturées, expédiées et retournées. Si le développeur a décidé d’émettre une requête sur cette table, nous verrions le résultat suivant dans notre plan de requête. (Remarque : le résultat ci-dessous a été effectué sur un entrepôt XS) :

image5


Cela a pris environ 19 secondes sur un entrepôt XS, ce qui n’est pas mal du tout. Cependant, nous pouvons voir que la requête effectuait toujours une analyse complète de la table et effectuait une assez bonne quantité d’agrégation.

Voyons maintenant comment nous pouvons améliorer l’expérience du développeur en créant un exemple d’ensemble de la table LINEITEM. Nous allons créer une vue spéciale (par rapport à notre base de données de développement clonée) pour ce développeur et l’appeler V_SALES_LINEITEM_SAMPLE_10. Dans cette vue, nous utiliserons la technique d’échantillonnage de blocs et n’analyserons que 10 % des partitions requises par cette requête.

Créez d’abord la vue :

create view v_Sales_LineItem_Sample_10 as

    select *

    from SALES.PUBLIC.LINEITEM

    sample block (10);

Ensuite, mettons à jour la requête pour utiliser la vue à la place.

select

       l_returnflag,

       l_linestatus,

       sum(l_quantity) as sum_qty,

       sum(l_extendedprice) as sum_base_price,

       sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,

       sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,

       avg(l_quantity) as avg_qty,

       avg(l_extendedprice) as avg_price,

       avg(l_discount) as avg_disc,

       count(*) as count_order

  from

       v_Sales_LineItem_Sample_10

where

       l_orderdate <= dateadd(day, -90, to_date('1998-12-01'))

group by

       l_returnflag,

       l_linestatus

 order by

       l_returnflag,

       l_linestatus;

Résultat:

image3

Examinons le profil de requête pour cette requête :

image2 1

Cette requête a duré environ 2,5 secondes sur un entrepôt XS et nous avons analysé environ 10 % de la partition totale de la table. Ce résultat est bien meilleur ! Snowflake échantillonne 10 % de la partition à extraire en fonction du filtre WHERE. Le résultat doit toujours être suffisamment précis pour permettre au développeur de savoir que cette requête fonctionne comme prévu.

En conclusion, tirer parti de la clause SAMPLE de Snowflake réduit considérablement la quantité de données de test pour un développeur sans perdre l’intégrité des données. Même si un identifiant spécifique ou un horodatage biaise les données natives, il y a de fortes chances que le développeur accepte la nuance et continue le développement au lieu de dépenser des crédits de calcul supplémentaires et des heures à attendre le retour des résultats. L’alternative consiste à utiliser la fonction LIMIT peut-être pour réduire le nombre de lignes renvoyées. Cependant, cela implique de modifier la requête d’origine ou de créer une vue qui doit encore être maintenue. À l’aide de la clause SAMPLE, vous pouvez créer un sous-ensemble fiable d’une grande table avec une combinaison de résultats et des performances acceptables. J’espère que ça t’as aidé. N’hésitez pas à laisser des commentaires dans notre communauté et à me faire part de vos réflexions.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.