Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4249333
  • 博文数量: 601
  • 博客积分: 15410
  • 博客等级: 上将
  • 技术积分: 6884
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-16 08:11
个人简介

独学而无友,则孤陋而寡闻!

文章分类

全部博文(601)

文章存档

2020年(1)

2018年(4)

2017年(7)

2016年(42)

2015年(25)

2014年(15)

2013年(36)

2012年(46)

2011年(117)

2010年(148)

2009年(82)

2008年(37)

2007年(41)

分类: Mysql/postgreSQL

2016-02-25 19:57:45

1、传统的,也是最慢的方式:

SELECT myid FROM mytable ORDER BY RANDOM() LIMIT 1;

缺点:近似于全表扫描,没有好的索引可以走;

2、稍微快一点的方式,用offset来实现:

SELECT myid FROM mytable OFFSET floor(random()*N) LIMIT 1;

3、德哥的实现方式,用函数实现:

  1. digoal=> create or replace function f_get_random (i_range int) returns setof record as $BODY$
  2. digoal$> declare
  3. digoal$> v_result record;
  4. digoal$> v_max_id int;
  5. digoal$> v_min_id int;
  6. digoal$> v_random numeric;
  7. digoal$> begin
  8. digoal$> select random() into v_random;
  9. digoal$> select max(id),min(id) into v_max_id,v_min_id from tbl_user;
  10. digoal$> for v_result in select * from tbl_user where id between (v_min_id+(v_random*(v_max_id-v_min_id))::int) and (v_min_id+(v_random*(v_max_id-v_min_id))::int+i_range)
  11. digoal$> loop
  12. digoal$> return next v_result;
  13. digoal$> end loop;
  14. digoal$> return;
  15. digoal$> end
  16. digoal$> $BODY$ language plpgsql;
  17. CREATE FUNCTION

  18. 以下举例取出10条连续的随机记录

  19. digoal=> select * from f_get_random(9) as (id bigint,firstname varchar(32),lastname varchar(32),corp varchar(32),age smallint);
  20.  

4、借助另一列的索引实现:

  1. create table randtest (id serial primary key, data int not null);
  2. insert into randtest (data) select (random()*1000000)::int from generate_series(1,1000000);
  3. create index randtest_md5_id_idx on randtest (md5(id::text));
  4. explain analyze
  5. select * from randtest where md5(id::text)>md5(random()::text) order by md5(id::text) limit 1;
5、9.5版用 TABLESAMPLE:
  1. SELECT * FROM my_table TABLESAMPLE SYSTEM(0.000001) LIMIT 1;



阅读(12633) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~