0

我希望加快此查询的速度。目前执行只需要 20 多秒,这太可怕了。

我找不到通过使用和 JOIN 函数删除子查询的方法。

SQL:

(

    SELECT
        `manual`.`id`,
        `fname`,
        `lname`,
        `email`,
        '' AS `company`,
        '' AS `level`,
        `completed_tests`.`assessment`,
        '' AS `st_ref`,
        '1' AS `manual`,
        `completed_tests`.`percentage`,
        '' AS `last_visit`,
        '' AS `joined`

    FROM
        `manual`

    LEFT JOIN `used_codes` ON `manual`.`id` = `used_codes`.`user` AND `used_codes`.`id` = (SELECT MAX(`id`) FROM `used_codes` WHERE `user` = `manual`.`id` AND `manual` = 1)
    LEFT JOIN `vcode` ON `manual`.`vcode` = `vcode`.`id`
    LEFT JOIN `groups` ON `vcode`.`group` = `groups`.`id`
    LEFT JOIN `completed_tests` ON `manual`.`id` = `completed_tests`.`user` AND `completed_tests`.`id` = (SELECT MAX(`id`) FROM `completed_tests` WHERE `user` = `manual`.`id` AND `manual` = 1)

)
UNION ALL
(

    SELECT
        `users`.`id`,
        `fname`,
        `lname`,
        `email`,
        `company`,
        `users`.`level`,
        `completed_tests`.`assessment`,
        `orders`.`st_ref`,
        '0' AS `manual`,
        `completed_tests`.`percentage`,
        `last_visit`,
        `joined`

    FROM
        `users`

    LEFT JOIN `orders` ON `users`.`id` = `orders`.`user` AND `orders`.`id` = (SELECT MAX(`id`) FROM `orders` WHERE `status` = 3 AND `user` = `users`.`id`)
    LEFT JOIN `used_codes` ON `users`.`id` = `used_codes`.`user` AND `used_codes`.`id` = (SELECT MAX(`id`) FROM `used_codes` WHERE `user` = `users`.`id` AND `manual` = 1)
    LEFT JOIN `vcode` ON `used_codes`.`vcode` = `vcode`.`id`
    LEFT JOIN `groups` ON `vcode`.`group` = `groups`.`id`
    LEFT JOIN `completed_tests` ON `users`.`id` = `completed_tests`.`user` AND `completed_tests`.`id` = (SELECT MAX(`id`) FROM `completed_tests` WHERE `user` = `users`.`id` AND `manual` = 0)

)

ORDER BY `lname` ASC, `fname` ASC;

为了让您了解数据库结构,有两个主要表,一个 forusers和一个 for manual。其他表包含附加数据,并与用户 ID 和另一个名为manual以查看他们属于哪个数据库。

我遇到的问题是我需要该用户的数据来显示他们在其他表中是否有任何其他数据。当我使用 JOIN 函数对此进行测试时,该记录将从结果中完全删除。

我认为需要重写的查询的主要部分是LEFT JOINs. 我无法找到与此相同的方法:LEFT JOIN orders ON users.id = orders.user AND orders.id = (SELECT MAX(id) FROM orders WHERE status = 3 AND user = users.id)

4

1 回答 1

1

如果您取出子查询,例如:

SELECT MAX(id) FROM orders WHERE status = 3 AND user = users.id

将它们放入临时表并索引 id。您绝对可以索引临时表,当我尝试优化子查询时,我已经看到它在性能上产生了巨大差异。

当然,您必须删除 user = user.id 部分,但您可以保留 status = 3 部分。

您为大查询支付一次费用(存储具有该状态的所有用户并索引临时表),但随后所有调用都非常快。

于 2013-06-07T17:09:30.993 回答