Oracle
 sql >> Database >  >> RDS >> Oracle

semplice campionamento casuale durante l'estrazione dei dati dal magazzino (motore Oracle) utilizzando proc sql in sas

Utilizzare il pacchetto DBMS_RANDOM per ordinare i record e quindi utilizzare una clausola di limitazione delle righe per limitare la dimensione del campione desiderata

La funzione dbms_random.value ottiene un numero casuale compreso tra 0 e 1 per tutte le righe della tabella e ordiniamo in ordine crescente il valore casuale.

Ecco come produrre il set di campioni che hai identificato:

    SELECT
    *
FROM
    (
        SELECT
            *
        FROM
            tbl1
        ORDER BY dbms_random.value
    )
FETCH FIRST 1000000 ROWS ONLY;

Per dimostrare con la tabella dello schema di esempio, emp , campioniamo 4 record:

   [email protected]> SELECT
  2      empno,
  3      rnd_val
  4  FROM
  5      (
  6          SELECT
  7              empno,
  8              dbms_random.value rnd_val
  9          FROM
 10              emp
 11          ORDER BY rnd_val
 12      )
 13  FETCH FIRST 4 ROWS ONLY;
EMPNO  RND_VAL
7698   0.06857749035643605682648168347885993709
7934   0.07529612360785920635181751566833986766
7902   0.13618520865865754766175030040204331697
7654   0.14056380246495282237607922497308953768


[email protected]> SELECT
  2      empno,
  3      rnd_val
  4  FROM
  5      (
  6          SELECT
  7              empno,
  8              dbms_random.value rnd_val
  9          FROM
 10              emp
 11          ORDER BY rnd_val
 12      )
 13  FETCH FIRST 4 ROWS ONLY;
EMPNO  RND_VAL
7839   0.00430658806761508024693197916281775492
7499   0.02188116061148367312927392115186317884
7782   0.10606515700372416131060633064729870016
7788   0.27865276349549877512032787966777990909

Con l'esempio sopra, nota che empno cambia in modo significativo durante l'esecuzione del comando SQL*Plus.

Il rendimento potrebbe essere un problema con il conteggio delle righe che stai descrivendo.

MODIFICA:

Con dimensioni del tavolo nell'ordine di 150 giga - 79 MM, qualsiasi smistamento sarebbe doloroso.

Se la tabella avesse una chiave surrogata basata su una sequenza incrementata di 1, potremmo adottare l'approccio di selezionare ogni ennesimo record in base alla chiave.

per esempio.

    --scenario n = 3000

 FROM
    tbl1
WHERE
    mod(table_id, 3000) = 0;

Questo approccio non utilizzerà un indice (a meno che non venga creato un indice basato su una funzione), ma almeno non stiamo eseguendo un ordinamento su un set di dati di queste dimensioni.

Ho eseguito un piano di spiegazione con una tabella che ha quasi 80 milioni di record ed esegue una scansione completa della tabella (la condizione lo costringe senza un indice basato sulla funzione), ma sembra sostenibile.