Re: random record from small set
От | Jan Poslusny |
---|---|
Тема | Re: random record from small set |
Дата | |
Msg-id | 4212225E.9010405@gingerall.cz обсуждение исходный текст |
Ответ на | Re: random record from small set (Jan Poslusny <pajout@gingerall.cz>) |
Список | pgsql-general |
Or create table r1 ( i int, chance_from numeric ) and select * from r1 where chance_from <= $rnd order by chance_from desc limit 1; which can be easier updated... Just ideas, I has never tested it... Jan Poslusny wrote: > And what about another data representation like > > create table r1 ( > i int, > chance_from numeric, > chance_to numeric > ) > , you can select one random row in one select, for instance > select * from r1 where chance_from <= $rnd and chance_to > $rnd; > > I see these advantages > - Only one select. > - Indices can improve performance if r1 has many rows. > and disadvantage > - Tricky update > > > Jeff Davis wrote: > >> I am trying to retrieve a random record (according to a chance >> attribute) from a small set of records, each with a "chance" attribute. >> This may eventually be somwhat of a performance concern, so I'd like to >> make sure I'm doing this right. >> >> Here's what I have so far: >> >> create table r1 ( >> i int, >> chance numeric >> ) >> create or replace function randrec() returns int as $$ >> $res = spi_exec_query('select i,chance from r1'); >> $r = rand; >> $accum = 0; >> $i = 0; >> while($accum < $r) { >> $accum += $res->{rows}[$i++]->{chance} >> } >> return $res->{rows}[$i-1]->{i}; >> $$ language plperl; >> >> test=# select * from r1; >> i | chance >> ---+-------- >> 1 | 0.25 >> 2 | 0.20 >> 3 | 0.15 >> 4 | 0.10 >> 5 | 0.30 >> >> >> That seems to work, in that out of 10k times, I got the following >> numbers of each: >> 1 2479 >> 2 1959 >> 3 1522 >> 4 950 >> 5 3090 >> >> But I have a few questions: >> * Am I right to use NUMERIC for the chance attribute? >> * Does perl's arithmetic leave me with the chance that those numeric >> values don't add up to 1.00 (and in this case that could mean an >> infinite loop)? >> * In my design I'll need a constraint trigger making sure that the >> numbers add up to 1.00. Will that be a performance problem for >> operations on the table that don't modify the chance attribute? >> * Is there a better way? >> * Does spi_exec_query pull the entire result set into memory at once? Is >> there a point at which performance could be a serious problem if there >> are a large number of items to select among? >> >> Regards, >> Jeff Davis >> >> >> >> ---------------------------(end of broadcast)--------------------------- >> TIP 2: you can get off all lists at once with the unregister command >> (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) >> >> >> >
В списке pgsql-general по дате отправления: