请教下我应该如何优化FOREACH语句呢

#1 阳光小老鼠

$inner_goods_id = $cvs_goods -> findAll("","","id");
   shuffle($inner_goods_id);
   $whole_goods = $inner_goods_id;
   $i = 0;
   foreach($whole_goods as $t => $y)
   {
    $i = $i + 1;
    $conditions = array('id'=>$y[id]);  
    $cvs_goods->updateField($conditions, 'goods_rand_whole', $i);
   }

我是通过FOREACH更新进入数据库的,当打开页面的时候真的很慢,因为数据几千条,有什么办法可以优化的没。

2012-01-05 23:19:50

#2 coolhpy

没必要单独存一个字段来实现随机排列吧

读取随机列表的时候,试试下面这段代码。。我用45000条数据测试,平均0.1秒的样子~
SELECT * 
FROM table_name AS r1 JOIN (
        SELECT ROUND(RAND() * (SELECT MAX(id) FROM table_name)) AS id
) AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC

2012-01-06 08:47:42

#3 coolhpy

刚刚又在网上找了一下,发现了一个上述代码的修正版,,可以查询出数据库中ID比较靠前的记录。。
如果不想取到连续的几条数据,可以多查询几次,每次取一条,毕竟效率还是不错的。
SELECT * 
FROM `table_name` AS t1 JOIN (
        SELECT ROUND(
                RAND() * (
                        (SELECT MAX(id) FROM `table_name`) - (SELECT MIN(id) FROM `table_name`)
                ) + (SELECT MIN(id) FROM `table_name`)
        ) AS id
) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id
LIMIT 10;

2012-01-06 09:05:33

#4 jake

突然发现楼主原来是update全表。。。

to coolhpy:因为是直接查出全部的ID再打乱,所以直接查出全部主键ID就是最快的方法了。AND,子查询是不能用索引的,所以更慢。。。

楼主的需求非常怪,乱序递增还是怎么?

真的只为做随机排序?

要知道,十个以上的随机排序rand函数的select 等于 一个update一行数据,为了随机排序而update全表,那是本末倒置的做法。

2012-01-06 09:10:47

#5 阳光小老鼠

其实我的做法是数据库内容都要查询出来,但如果用RAND 会重复,有分页就没用了,所以先打乱顺序在读取出来的

2012-01-06 14:10:19

#6 阳光小老鼠

回复 2 coolhpy


    可以不用随机吗  不然会有重复的

2012-01-06 14:11:01

#7 阳光小老鼠

回复 4 jake


    因为商品都是固定的,所以我设置了每4个小时重新随便排序一次的做法

2012-01-06 14:11:30

#8 jake

回复  jake


    因为商品都是固定的,所以我设置了每4个小时重新随便排序一次的做法 ...
阳光小老鼠 发表于 2012-1-6 14:11
有个方法,四小时随机排序一次,而且不会重复。

1. 全部ID查出来,打乱,放到memcache或者文件缓存里面
2. 每四小时从缓存里面取一批ID出来,缓存里丢掉这部分3. ID再查数据库取得这一批的数据,用IN(id)作为条件,因为是主键IN,所以可以用索引,速度快。

2012-01-06 14:39:54

#9 阳光小老鼠

回复 8 jake


    这种写法 我还真没写过  可以教教我怎么写吗

2012-01-06 17:54:13

#10 阳光小老鼠

memcache  虚拟主机 应该没这个吧

2012-01-06 17:58:03

#11 jake

没有就用文件缓存,spAccess

跟你上面做得差不多,只是不再update了。取出一次全部ID,打乱然后放到spAccess里面。

然后每次取出来后,截取前面n条(PHP有数组截取函数)。

用n条ID用IN查询,余下的数组放回spAccess里面。

一直重复直到spAccess没有数据了,再来一次

2012-01-06 18:07:39

#12 阳光小老鼠

回复 11 jake


    spAccess 这个文件是存在哪里的呢

2012-01-06 21:35:22

#13 阳光小老鼠

回复 11 jake


    还想在问下,我通过spAccess 这个可以了,但如何进行分页函数的运用呢,分页函数spArgs都是对应findAll的

2012-01-06 21:43:28

#14 jake

分页要自己写了

2012-01-06 21:58:07

#15 阳光小老鼠

回复 14 jake


    啊天啊 群里面有分页函数不  或者 群主你有写的分页函数送个好吗

2012-01-06 21:59:45

#16 jake

回复  jake


    啊天啊 群里面有分页函数不  或者 群主你有写的分页函数送个好吗 ...
阳光小老鼠 发表于 2012-1-6 21:59
搜索一下吧

2012-01-06 22:05:48