随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_数据库

随机记录的获取这样的需求可能会经常有,例如审核,抽查,采样,等需求,当然还有抽奖程序这样的需求。

每种数据库获取随机记录的方法也不尽相同,下面就来盘点一下各种数据库在取随机数的方法和可能存在的问题。

1  MYSQL 

一般的情况下MYSQL 的随机记录获取都是通过  rand() 函数来做的,具体方法

select * from dd_batch_info order by rand() limit 10;

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_SQL_02

但这样的取数方法有一个弊病就是效率太低

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_主键_03

反过来,下面的方法就会比较好一些,(当然也有他的问题)

select t.*

from dd_batch_info as t

inner join (

select round(rand() * 

(select max(id) from dd_batch_info) 

) as id

) as idd

where t.id = idd.id;

上面的方法比较直接使用 order by rand 的方法好处在于快,如果你的数据量在 1000万的时候,用上面的方法还是会很快的出结果,(秒出),而遍历1000万数据在选出几条这样的写法就很不OK了。

两种方法都OK ,但效率不一样,这就如同人生做的事情一下,1天 2 天,做法不同或许不会有什么,如果1 年 2 年 10年 ,用不同的方法去处理人生的事情,那我想每个人的人生都会如同现在,五彩斑斓。

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_SQL_04

说完了 MYSQL ,继续来看看 ORACLE 

我们还是要取随机的记录,怎么办,

 select * from ext_log where rownum <=3

  order by dbms_random.value

这样写看似是不是没有问题,我们来运行一下

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_主键_05

那如果在多运行几次呢,是不是发现结果怎么一样。

那是不是哪里出了问题,问题再取数据和排序的顺序错误了。那正确应该怎么写。

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_数据库_06

上面的写法,的确是随机获得了数据,但是不是又产生新的问题了,效率太慢。那该怎么写,可以参考一下MYSQL的 想法来写这个SQL ,有助于提高效率。

数据量小和数据量大,看似是量变,但量变的太大,就不得不考虑性能问题。

SQL SERVER 又如何呢, 下面这个就是求随机值的一种方式,为什么这样写,主要原因是表的主键是不大好进行排序的和进行计算的,所以才废了这样的功夫,如果主键是方便进行计算的,则不需要这么麻烦。并且性能也不会很差,当然下面的语句性能其实不是特别好,如果有其他方法,可以发给我哈  liuausitn3@hotmail.com (感谢)

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_主键_07

with data_1  as(

select  row_number() over ( order by id desc ) as tid1,id

from CACONTRACT )

,

row_num as(

select  cast(cast(max(tid) as float) * rand() as int) as tid2

from 

(select  row_number() over ( order by id desc )as tid, id from CACONTRACT ) as tt) 

select data_1.tid1,data_1.id

from row_num as row_num

inner join data_1 as data_1 on data_1.tid1 = row_num.tid2

最后轮到 POSTGRESQL ,

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_SQL_08

但是这样做性能在大数据量上是一个问题。

select d.*

from (select floor(random() * (max(id) - min(id))) as id from test_d) as ma

inner join test_d as d on ma.id = d.id;

通过以上方法来做的情况下,每次生产一个随机记录 1.1秒 而 不采用这样的方法直接使用最上面的方法,则需要2.2秒,以上测试时在100万数据行中进行测试的。

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_主键_09

最后,来点鸡汤,最近听了一个关于特斯拉的发展经历的一个音频节目,给我的印象是,任何新的创业都是经历了很多不确定性,可能大家一致看好的东西,项目,在发展的过程中,失败了,或成功了,可能事后总结出很多失败和成功的原因,但不确定因素大多没有写到这些记录里面,就如同本期的随机记录,

Life is like a box of chocolate. You never know what you're gonna get next.  失败了也别觉得自己不行,成功了也别觉得那是应得的。

随机记录如何获取之  ORACLE MYSQL SQL SERVER POSTGRESQL_SQL_10