![]() |
|
|||||||
![]() |
|
|
Thread Tools | Display Modes |
|
#1
IP: 112.87.0.107
|
|||
|
|||
|
mysql随机查询的优化 mysql随机函数RAND()的使用方法
mysql随机查询最常见的写法如下: SELECT * FRO M tablename ORDER BY RAND() LIMIT 1 php手册上如此解释: About selecting random rows from a MySQL table: SELECT * FROM tablename ORDER BY RAND() LIMIT 1 works for small tables, but once the tables grow larger than 300,000 records or so this will be very slow because MySQL will have to process ALL the entries from the table, order them randomly and then return the first row of the ordered result, and this sorting takes long time. Instead you can do it like this (atleast if you have an auto_increment PK): SELECT MIN(id), MAX(id) FROM tablename; Fetch the result into $a $id=rand($a[0],$a[1]); SELECT * FROM tablename WHERE id>='$id' LIMIT 1 大意是说,如果你用 ORDER BY RAND() 来随机读取记录的话,当数据表记录达到30万或者更多的时候,mysql将非常吃力. 所以php手册里给了一种方法,结合php来实现: 首先 SELECT MIN(id), MAX(id) FROM tablename; 取数据库里最大最小值; 然后 $id=rand($a[0],$a[1]); 产生一个随机数; 最后 SELECT * FROM tablename WHERE id>='$id' LIMIT 1 将上面产生的随机数带入查询; -------- 本人观点,很显然上面是最有效率的,但是本人只会C#开发Form,如果会php可以直接修改ecms的代码,自己做个随机标签,看来有空要加强php的学习 ======================== mysql随机查询的优化 mysql随机函数RAND()的使用方法 搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据。 SELECT* FROM`table`ASt1JOIN(SELECTROUND(RAND()*(SELECTMAX(id)FROM`table`))ASid)ASt2 WHEREt1.id>=t2.id ORDERBYt1.idASCLIMIT1;《《自用推荐,要几条结果就循环几次 但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。 上面的语句采用的是JOIN,mysql的论坛上有人使用 SELECT* FROM`table` WHEREid>=(SELECTFLOOR(MAX(id)*RAND())FROM`table`) ORDERBYidLIMIT1; 我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。 于是我把语句改写了一下。 SELECT*FROM`table` WHEREid>=(SELECTfloor(RAND()*(SELECTMAX(id)FROM`table`))) ORDERBYidLIMIT1; 这下,效率又提高了,查询时间只有0.01秒 最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。 完整查询语句是: SELECT*FROM`table` WHEREid>=(SELECTfloor(RAND()*((SELECTMAX(id)FROM`table`)-(SELECTMIN(id)FROM`table`))+(SELECTMIN(id)FROM`table`))) ORDERBYidLIMIT1; ================ SELECT* FROM`table`ASt1JOIN(SELECTROUND(RAND()*((SELECTMAX(id)FROM`table`)-(SELECTMIN(id)FROM`table`))+(SELECTMIN(id)FROM`table`))ASid)ASt2 WHEREt1.id>=t2.id ORDERBYt1.idLIMIT1; 最后在php中对这两个语句进行分别查询10次, ---------- 本人看法 上面这句sql有问题,出现的问题是 ①:随机id是连续的 ② :数据库存储的信息不大时,偶尔的Error报警,无返回。 ③ :有几率出现两次同样的结果 --------------------- 前者花费时间 0.147433 秒 后者花费时间 0.015130 秒 看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。 真晕,刚试了一下,中间那个计算,完全可以采用如下方式进行: select round(rand()*(max(a.id)-min(a.id)))+min(a.id) from table a; |
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
|
|