优化几个MySQL(子)查询

时间:2014-09-07 10:36:29

标签: php mysql sql mysqli

我有一些很大的问题要找到与我的用户玩一个大桌子的最佳方法:

功能以这种方式运作:人们可以玩两种不同的游戏并通过这种方式获得游戏币。另外,他们引用了用户,他们也从中获得了余额。我当前的查询需要永远,看起来像这样:

$sql = $mysqli->query("SELECT 
    n.id, n.account, n.email, n.lastpayout, n.referupnumber, 
    (SELECT sum(r.win) FROM rolls r WHERE r.konto = n.id AND r.zeit > n.lastpayout) as sumroll,
    (SELECT sum(m.gewinn) FROM multi m WHERE m.account = n.id AND m.zeit > n.lastpayout) as summulti,
    (SELECT count(nx.referupnumber) FROM nxt_account nx WHERE nx.referupnumber = n.id) as amountref
FROM
    nxt_account n");

$amountuser = $sql->num_rows;
$c = 1;  
while($row = $sql->fetch_array()) {

    $id_thistime = $row['id'];
    $sql_ref = $mysqli->query("SELECT 
    nn.id,
    (SELECT 
            sum(rr.win)
        FROM
            rolls rr
        WHERE
            rr.zeit >= nn.lastpayout AND rr.konto = n.id) as refamount
FROM
    nxt_account nn
WHERE
    nn.referupnumber = '".$id_thistime."'");
    $total_ref = 0;

while($row_ref = $sql_ref->fetch_array()) {

    $total_ref = $total_ref + $row_ref['refamount'];

}

$total_amount = $row['sumroll'] + $row['summulti'] + $total_ref;   }

非常感谢你,如果你能理解这一点,并给我任何提示如何优化这些查询。

2 个答案:

答案 0 :(得分:2)

这是查询:

SELECT n.id, n.account, n.email, n.lastpayout, n.referupnumber, 
       (SELECT sum(r.win) FROM rolls r WHERE r.konto = n.id AND r.zeit > n.lastpayout) as sumroll,
       (SELECT sum(m.gewinn) FROM multi m WHERE m.account = n.id AND m.zeit > n.lastpayout) as summulti,
       (SELECT count(nx.referupnumber) FROM nxt_account nx WHERE nx.referupnumber = n.id) as amountref
FROM nxt_account n;

您从多个表中引入数据,因此这是一个合理的结构。我建议使用以下索引:

rolls(konto, zeit, win)
multi(account, zeit, gewinn)
nxt_account(referupnumber)

这应该加快子查询并提高性能。

答案 1 :(得分:1)

我建议您将主查询更改为此并根据一个数据库请求进行所有计算:

    SELECT 
        n.id, n.account, n.email, n.lastpayout, n.referupnumber, 
        (SELECT sum(r.win) 
         FROM rolls r 
         WHERE r.konto = n.id AND r.zeit > n.lastpayout) as sumroll,
        (SELECT sum(m.gewinn) 
         FROM multi m 
         WHERE m.account = n.id AND m.zeit > n.lastpayout) as summulti,
        (SELECT count(nx.referupnumber) 
         FROM nxt_account nx 
         WHERE nx.referupnumber = n.id) as amountref,
        (SELECT sum(rr.win)
         FROM  rolls rr INNER JOIN nxt_account nn ON
            rr.zeit >= nn.lastpayout AND rr.konto = n.id
         WHERE nn.referupnumber =n.id) as refamount
    FROM
        nxt_account n

完成它的方式与nxt_account表中的记录一样多。这可能是计算速度缓慢的主要原因。

如果您只需要所有帐户的一个总计数,您也应该在SQL中进行计算。