对于循环执行时间

时间:2018-01-12 08:55:48

标签: php

我的数据库包含200个数据,我正在尝试执行for循环来检查用户的下线,并根据他们的下线为他们分配级别,但是执行时间太长,因此服务器没有及时响应。我该怎么办?

$query2 = mysqli_query($conn,"SELECT * FROM members LIMIT 1");
$row3 = mysqli_fetch_assoc($query2);
$id=$row3['id']; 

for ($i=$id;  ; $i++) {  
    $query2 = mysqli_query($conn,"SELECT * FROM members WHERE d!=0 AND id=".$i);
    $row3 = mysqli_fetch_assoc($query2);
    $level1=$row3['level'];
    $d=$row3['d'];
    $downline1=$row3['downline'];
    if ($d!=$downline1) {
        switch ($level1) {
        case 1:
            $downline1=($d-3);
            mysqli_query($conn,"UPDATE members SET downline='$downline1' WHERE id=".$i);
            break;
        case 2:
            $downline1=($d-12);
            mysqli_query($conn,"UPDATE members SET downline='$downline1' WHERE id=".$i);
            break;
        case 3:
            $downline1=($d-39);
            mysqli_query($conn,"UPDATE members SET downline='$downline1' WHERE id=".$i);
            break;
        case 4:
            $downline1=($d-120);
            mysqli_query($conn,"UPDATE members SET downline='$downline1' WHERE id=".$i);
            break;
        case 5:
            $downline1=($d-363);
            mysqli_query($conn,"UPDATE members SET downline='$downline1' WHERE id=".$i);
            break;

        }

        $query1=mysqli_query($conn,"SELECT * FROM downline");
        while($row = mysqli_fetch_assoc($query1)) {
            $level=$row['level'];
            $downline=$row['total_downline'];
            if ($downline1==$downline){
                mysqli_query($conn,"UPDATE members SET level='$level' WHERE id=".$i);
            }
        }   
    }

2 个答案:

答案 0 :(得分:1)

你的for循环是一个无限循环,因为你没有定义一个结束条件:for ($i=$id; ; $i++) {

最好是获取所有成员并使用while循环迭代它们:

$query2 = mysqli_query($conn,"SELECT * FROM members");
while($row3 = mysqli_fetch_assoc($query2)){
    $id = $row3['id'];
    // do what you used to do in for-loop here
} 

通过这种方式,您可以遍历数据库中的所有成员,即使他们的ID如Barmar所提到的那样存在空白。

在旁注中,将更新查询从switch-cases内移动到切换后。每种情况都是一样的。

编辑:从数据库

修复了抓取成员

答案 1 :(得分:1)

如果您正在尝试更新所有成员,则不需要执行SELECT和循环,只需将所有逻辑放在SQL中:

UPDATE members
SET downline = d - CASE level
                    WHEN 1 THEN 3
                    WHEN 2 THEN 12
                    WHEN 3 THEN 39
                    WHEN 4 THEN 120
                    WHEN 5 THEN 363
                END
WHERE d BETWEEN 1 AND 5 AND d != downline

然后第二次更新可以是:

UPDATE members AS m
JOIN downline AS d ON m.downline = d.total_downline
SET m.level = d.level
WHERE m.d BETWEEN 1 AND 5

您实际上可以同时进行两项更新:

UPDATE members AS m
LEFT JOIN downline AS d 
ON m.d = d.total_downline +
    CASE level
        WHEN 1 THEN 3
        WHEN 2 THEN 12
        WHEN 3 THEN 39
        WHEN 4 THEN 120
        WHEN 5 THEN 363
    END
SET m.level = IFNULL(d.level, m.level), 
    m.downline = m.d - CASE level
                        WHEN 1 THEN 3
                        WHEN 2 THEN 12
                        WHEN 3 THEN 39
                        WHEN 4 THEN 120
                        WHEN 5 THEN 363
                    END
WHERE m.d BETWEEN 1 AND 5 AND m.d != m.downline