MySQL效率/使用子查询的最佳实践与多次相同的计算

时间:2012-10-05 09:55:11

标签: mysql subquery

多次使用子查询与计算的最佳做法是什么?到目前为止我使用过子查询,但是当你只需要一个从前一个查询计算的变量时,它们看起来很荒谬(在下面的例子中,我们讨论的是带有子查询的子查询的查询)。

那么哪种方法/最佳实践方法?就个人而言,作为程序员,我身上的一切都告诉我使用方法a,因为它似乎似乎愚蠢地复制粘贴计算,但与此同时,子查询并不总是很好看,因为它可以使查询使用filesort而不是索引排序(请纠正我,如果我错了,请)。

方法a - 子查询

SELECT
    tmp2.*
FROM
    (
        SELECT
            tmp.*,
            (NOW() < tmp.expire_time) as `active`
        FROM
            (
                SELECT
                    tr.orderid,
                    tr.transactiontime,
                    pa.months as `months`,
                    DATE_ADD(tr.transactiontime, INTERVAL pa.months MONTH) as `expire_time`
                FROM
                    `transactions` as `tr`
                INNER JOIN
                    `packages` as `pa`
                ON
                    tr.productid = pa.productid
                WHERE
                    tr.isprocessed = '1'
                ORDER BY
                    tr.transactiontime ASC
            ) as `tmp`
    ) as `tmp2`
WHERE
    tmp2.active = 1

说明:

subqueries

方法b - 重复使用计算

SELECT
    tr.orderid,
    tr.transactiontime,
    pa.months as `months`,
    DATE_ADD(tr.transactiontime, INTERVAL pa.months MONTH) as `expire_time`,
    (NOW() < DATE_ADD(tr.transactiontime, INTERVAL pa.months MONTH)) as `active`
FROM
    `transactions` as `tr`
INNER JOIN
    `packages` as `pa`
ON
    tr.productid = pa.productid
WHERE
    tr.isprocessed = '1'
AND
    (NOW() < DATE_ADD(tr.transactiontime, INTERVAL pa.months MONTH))
ORDER BY
    tr.transactiontime ASC

说明: enter image description here

注意DATE_ADD(tr.transactiontime, INTERVAL pa.months MONTH)重复3次,(NOW() < DATE_ADD(tr.transactiontime, INTERVAL pa.months MONTH))重复2次。

使用EXPLAINs似乎方法B要好得多,但我仍然不喜欢它必须进行3次相同的计算(我假设它这样做,并且不保存结果并替换所有实例本身。)。

1 个答案:

答案 0 :(得分:0)

您应该查看MySQL的EXPLAIN命令:

http://dev.mysql.com/doc/refman/5.0/en/explain.html

告诉你MySQL如何执行查询。