Userei il ROWID:
UPDATE xyz SET x='Y' WHERE rowid IN (
SELECT r FROM (
SELECT ROWID r FROM xyz ORDER BY dbms_random.value
) RNDM WHERE rownum < n+1
)
Il vero motivo per cui userei ROWID non è per l'efficienza (farà comunque una scansione completa della tabella):il tuo SQL potrebbe non aggiornare il numero di righe desiderate se la colonna m
non è unico.
Con solo 1000 righe, non dovresti davvero preoccuparti dell'efficienza (forse con cento milioni di righe). Senza alcun indice su questa tabella, sei bloccato a eseguire una scansione completa della tabella per selezionare record casuali.
[MODIFICA:] "E se ci fossero 100.000 righe"
Bene, sono ancora 3 ordini di grandezza inferiori a 100 milioni.
Ho eseguito quanto segue:
create table xyz as select * from all_objects;
[creato circa 50.000 righe sul mio sistema - non indicizzate, proprio come la tua tabella]
UPDATE xyz SET owner='Y' WHERE rowid IN (
SELECT r FROM (
SELECT ROWID r FROM xyz ORDER BY dbms_random.value
) RNDM WHERE rownum < 10000
);
commit;
Ci sono voluti circa 1,5 secondi. Forse era 1 secondo, forse fino a 3 secondi (non è stato formalmente cronometrato, ci è voluto solo abbastanza tempo per battere le palpebre).