Použil bych 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
)
Skutečným důvodem, proč bych použil ROWID, však není efektivita (stále bude provádět úplné skenování tabulky) - vaše SQL nemusí aktualizovat požadovaný počet řádků, pokud sloupec m
není jedinečný.
S pouhými 1000 řádky byste se opravdu neměli bát o efektivitu (možná se sto miliony řádků). Bez jakéhokoli indexu v této tabulce se zaseknete při úplném prohledávání tabulky za účelem výběru náhodných záznamů.
[UPRAVIT:] „Co když ale existuje 100 000 řádků“
No, to je pořád o 3 řády méně než 100 milionů.
Spustil jsem následující:
create table xyz as select * from all_objects;
[vytvořil v mém systému asi 50 000 řádků – neindexovaných, stejně jako vaše tabulka]
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;
To trvalo přibližně 1,5 sekundy. Možná to byla 1 sekunda, možná až 3 sekundy (formálně to nebylo načasováno, jen to trvalo dost dlouho, než mrklo).