Prendendo in prestito la tabella di esempio di Jonearles, vedo esattamente la stessa cosa (in 11gR2 su un'immagine di uno sviluppatore OEL), di solito ottenendo valori per a
fortemente inclinato verso 1
; con campioni di piccole dimensioni a volte non ne vedo affatto. Con il passaggio aggiuntivo di randomizzazione/restrizione che ho menzionato in un commento:
select a, count(*) from (
select * from test1 sample (1)
order by dbms_random.value
)
where rownum < 101
group by a;
... con tre run ho ottenuto:
A COUNT(*)
---------- ----------
1 71
2 29
A COUNT(*)
---------- ----------
1 100
A COUNT(*)
---------- ----------
1 64
2 36
Sì, il 100% è davvero tornato come 1
alla seconda corsa. L'inclinazione stessa sembra essere piuttosto casuale. Ho provato con il block
modificatore che sembrava fare poca differenza, forse sorprendentemente - avrei potuto pensare che sarebbe peggiorato in questa situazione.
È probabile che sia più lento, sicuramente per campioni di piccole dimensioni, poiché deve colpire l'intero tavolo; ma mi dà abbastanza anche divisioni abbastanza coerenti:
select a, count(*) from (
select a, b from (
select a, b, row_number() over (order by dbms_random.value) as rn
from test1
)
where rn < 101
)
group by a;
Con tre run ho ottenuto:
A COUNT(*)
---------- ----------
1 48
2 52
A COUNT(*)
---------- ----------
1 57
2 43
A COUNT(*)
---------- ----------
1 49
2 51
... che sembra un po' più sano. YMMV ovviamente.
Questo articolo di Oracle
copre alcune tecniche di campionamento e potresti voler valutare ora_hash
approccio e la versione stratificata se i tuoi dati si diffondono e le tue esigenze di "rappresentanza" lo richiedono.