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;

usersデータベース構造を理解するために、 用と用の 2 つのメイン テーブルがありますmanual。他のテーブルには追加のデータが保持され、ユーザーの ID とリンクされており、ユーザーがmanual属しているデータベースを確認するために呼び出される別のフィールドがあります。

私が抱えている問題は、他のテーブルに追加のデータがあるかどうかを示すために、そのユーザーのデータが必要なことです。JOIN 関数を使用してこれをテストしたところ、レコードは結果から完全に削除されました。

LEFT JOIN書き換えが必要なクエリの主要部分はsだと思います。私はこれと同じことをする方法を見つけることができません: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 の部分はそのままにしておくことができます。

大きなクエリ (そのステータスを持つすべてのユーザーを保存し、一時テーブルにインデックスを作成する) に対しては 1 回の料金を支払いますが、その後のすべての呼び出しは非常に高速です。

于 2013-06-07T17:09:30.993 に答える