Catégories :

Syntaxe de requête

SAMPLE / TABLESAMPLE

Renvoie un sous-ensemble de lignes échantillonnées aléatoirement à partir de la table spécifiée. Les méthodes d’échantillonnage suivantes sont prises en charge :

  • Échantillonner une fraction d’une table, avec une probabilité spécifiée pour l’inclusion d’une ligne donnée. Le nombre de lignes renvoyées dépend de la taille de la table et de la probabilité demandée. Un seed peut être spécifié pour rendre l’échantillonnage déterministe.

  • Échantillonner un nombre fixe et spécifié de lignes. Le nombre exact de lignes spécifiées est renvoyé à moins que la table ne contienne moins de lignes.

SAMPLE et TABLESAMPLE sont synonymes et peuvent être utilisés de manière interchangeable.

Syntaxe

SELECT ...
FROM ...
  { SAMPLE | TABLESAMPLE } [ samplingMethod ] ( { <probability> | <num> ROWS } ) [ { REPEATABLE | SEED } ( <seed> ) ]
[ ... ]

Où :

samplingMethod ::= { { BERNOULLI | ROW } |
                     { SYSTEM | BLOCK } }
BERNOULLI | ROW ou . SYSTEM | BLOCK

Spécifie la méthode d’échantillonnage à utiliser :

  • BERNOULLI (ou ROW) Inclut chaque ligne avec une probabilité de p/100. Semblable au tirage à pile ou face d’une pièce pondérée pour chaque ligne.

  • SYSTEM (ou BLOCK) : inclut chaque bloc de lignes avec une probabilité de p/100. Semblable au tirage à pile ou face d’une pièce pondérée pour chaque bloc de lignes. Cette méthode ne prend pas en charge l’échantillonnage à taille fixe.

La méthode d’échantillonnage est facultative. Si aucune méthode n’est spécifiée, la valeur par défaut est BERNOULLI.

probabilité ou . num ROWS

Spécifie si l’échantillonnage doit être basé sur une fraction de la table ou sur un nombre fixe de lignes de la table, où :

  • probabilité spécifie le pourcentage de probabilité à utiliser pour la sélection de l’échantillon. Peut être n’importe quel nombre décimal entre 0 (aucune ligne sélectionnée) et 100 inclus (toutes les lignes sélectionnées).

  • num spécifie le nombre de lignes (jusqu’à 1 000 000) à échantillonner dans la table. Peut être n’importe quel entier entre 0 (aucune ligne sélectionnée) et 1000000 inclus.

REPEATABLE | SEED ( seed )

Spécifie une valeur seed pour rendre l’échantillonnage déterministe. Peut être n’importe quel entier entre 0 et 2147483647 inclus.

Notes sur l’utilisation

  • Les mots-clés suivants peuvent être utilisés de manière interchangeable :

    • SAMPLE | TABLESAMPLE

    • BERNOULLI | ROW

    • SYSTEM | BLOCK

    • REPEATABLE | SEED

  • Le nombre de lignes renvoyées dépend de la méthode d’échantillonnage spécifiée :

    Basé sur une fraction
    • Pour l’échantillonnage BERNOULLI | ROW, le nombre attendu de lignes renvoyées est (p/100)*n.

    • Pour l’échantillonnage SYSTEM | BLOCK, l’échantillon peut être biaisé, en particulier pour les petites tables.

    Note

    Pour les très grandes tables, la différence entre les deux méthodes devrait être négligeable.

    De plus, comme l’échantillonnage est un processus probabiliste, le nombre de lignes renvoyées n’est pas exactement égal à (p/100)*n lignes, mais il s’en approche.

    • Si aucune valeur seed n’est spécifiée, SAMPLE génère des résultats différents lorsque la même requête est répétée.

    • Si une table ne change pas et que les mêmes valeurs seed et probabilité sont spécifiées, SAMPLE génère le même résultat. Cependant, l’échantillonnage sur une copie d’une table peut ne pas donner le même résultat que l’échantillonnage sur la table d’origine, même si les mêmes valeurs probabilité et seed sont spécifiées.

    Taille fixe
    • Si la table est plus grande que le nombre de lignes demandé, le nombre de lignes demandé est toujours renvoyé.

    • Si la table est plus petite que le nombre de lignes demandé, la table entier est renvoyée.

    • SYSTEM | BLOCK et seed ne sont pas pris en charge pour l’échantillonnage de taille fixe. Par exemple, les requêtes suivantes produisent des erreurs :

      select * from example_table sample system (10 rows);
      
      select * from example_table sample row (10 rows) seed (99);
      
  • L’échantillonnage avec une valeur seed n’est pas pris en charge sur les vues ou les sous-requêtes. Par exemple, la requête suivante produit une erreur :

    select * from (select * from example_table) sample (1) seed (99);
    
  • L’échantillonnage du résultat d’un JOIN est autorisé, mais uniquement lorsque tous les éléments suivants sont vrais :

    • L’échantillon est basé sur des lignes (Bernoulli).

    • L’échantillonnage n’utilise pas de valeur seed.

    L’échantillonnage est effectué après le traitement complet de la jointure. Par conséquent, l’échantillonnage ne réduit pas le nombre de lignes jointes ni le coût du JOIN. La section Exemples inclut un exemple d’échantillonnage du résultat d’un JOIN.

  • En plus d’utiliser des littéraux pour spécifier probabilité | num ROWS et seed, vous pouvez également utiliser des variables de session ou de liaison.

Remarques sur les performances

  • SYSTEM | BLOCK est souvent plus rapide que l’échantillonnage BERNOULLI | ROW.

  • L’échantillonnage sans seed est souvent plus rapide que celui avec seed.

  • L’échantillonnage à taille fixe peut être plus lent que l’échantillonnage équivalent basé sur une fraction parce que l’échantillonnage à taille fixe empêche une certaine optimisation des requêtes.

Exemples

Échantillonnage de lignes basé sur une fraction

Renvoie un échantillon d’une table dans lequel chaque ligne a une probabilité de 10 % d’être incluse dans l’échantillon :

SELECT * FROM testtable SAMPLE (10);

Renvoie un échantillon d’une table dans lequel chaque ligne a une probabilité de 20,3 % d’être incluse dans l’échantillon :

SELECT * FROM testtable TABLESAMPLE BERNOULLI (20.3);

Renvoie une table entière, comprenant toutes les lignes de la table :

SELECT * FROM testtable TABLESAMPLE (100);

Renvoyer un échantillon vide :

SELECT * FROM testtable SAMPLE ROW (0);

Cet exemple montre comment échantillonner plusieurs tables dans une jointure :

SELECT i, j
    FROM
         table1 AS t1 SAMPLE (25)     -- 25% of rows in table1
             INNER JOIN
         table2 AS t2 SAMPLE (50)     -- 50% of rows in table2
    WHERE t2.j = t1.i
    ;

La clause SAMPLE s’applique à une seule table, pas à toutes les tables précédentes ni à l’expression entière antérieure à la clause SAMPLE. L’opération JOIN suivante joint toutes les lignes de t1 à un échantillon de 50 % des lignes de la table2 ; il n’échantillonne pas 50 % des lignes résultant de la jointure de toutes les lignes des deux tables :

SELECT i, j
    FROM table1 AS t1 INNER JOIN table2 AS t2 SAMPLE (50)
    WHERE t2.j = t1.i
    ;

Pour appliquer la clause SAMPLE au résultat d’un JOIN, et non aux tables individuelles du JOIN, appliquez le JOIN à une vue en ligne contenant le résultat du JOIN. Par exemple, exécutez le JOIN en tant que sous-requête, puis appliquez le SAMPLE au résultat de la sous-requête. L’exemple ci-dessous échantillonne environ 1 % des lignes renvoyées par JOIN :

select *
   from (
         select *
            from t1 join t2
               on t1.a = t2.c
        ) sample (1);

Échantillonnage par blocs sur la base d’une fraction (avec seeds)

Renvoie un échantillon d’une table dans lequel chaque bloc de lignes a une probabilité de 3 % d’être inclus dans l’échantillon, et règle le seed sur 82 :

SELECT * FROM testtable SAMPLE SYSTEM (3) SEED (82);

Renvoie un échantillon d’une table dans lequel chaque bloc de lignes a une probabilité de 0,012 % d’être inclus dans l’échantillon, et règle le seed sur 99992 :

SELECT * FROM testtable SAMPLE BLOCK (0.012) REPEATABLE (99992);

Note

Si l’une ou l’autre de ces requêtes est exécutée à nouveau sans apporter aucune modification à la table, elles renvoient le même échantillon.

Échantillonnage de ligne à taille fixe

Renvoie un échantillon de taille fixe de 10 lignes dont chaque ligne a une probabilité de max(1, 10/n) d’être incluse dans l’échantillon, où n est le nombre de lignes dans la table :

SELECT * FROM testtable SAMPLE (10 ROWS);