Eu usaria o 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
)
O motivo real pelo qual eu usaria ROWID não é para eficiência (ele ainda fará uma verificação completa da tabela) - seu SQL pode não atualizar o número de linhas que você deseja se a coluna
m
não é único. Com apenas 1.000 linhas, você não deveria se preocupar com a eficiência (talvez com cem milhões de linhas). Sem nenhum índice nesta tabela, você fica preso fazendo uma varredura completa da tabela para selecionar registros aleatórios.
[EDIT:] "Mas e se houver 100.000 linhas"
Bem, isso ainda é 3 ordens de magnitude inferior a 100 milhões.
Eu corri o seguinte:
create table xyz as select * from all_objects;
[criou cerca de 50.000 linhas no meu sistema - não indexado, assim como sua tabela]
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;
Isso levou aproximadamente 1,5 segundos. Talvez tenha sido 1 segundo, talvez até 3 segundos (não foi formalmente cronometrado, apenas levou tempo suficiente para piscar).