MySQL查询占用了太多时间

时间:2017-08-01 15:46:56

标签: mysql query-performance

查询需要1分钟才能获取结果

SELECT 
`jp`.`id`,
`jp`.`title` AS game_title,
`jp`.`game_type`,
`jp`.`state_abb` AS game_state,
`jp`.`location` AS game_city,
`jp`.`zipcode` AS game_zipcode,
`jp`.`modified_on`,
`jp`.`posted_on`,
`jp`.`game_referal_amount`,
`jp`.`games_referal_amount_type`,
`jp`.`status`,
`jp`.`is_flaged`,
`u`.`id` AS employer_id,
`u`.`email` AS employer_email,
`u`.`name` AS employer_name,
`jf`.`name` AS game_function,
`jp`.`game_freeze_status`,
`jp`.`game_statistics`,
`jp`.`ats_value`,
`jp`.`integration_id`,
`u`.`account_manager_id`,
`jp`.`model_game`,
`jp`.`group_id`,
(CASE
    WHEN jp.group_id != '0' THEN gm.group_name
    ELSE 'NA'
END) AS group_name,
`jp`.`priority_game`,
(CASE
    WHEN jp.country != 'US' THEN jp.country_name
    ELSE ''
END) AS game_country,
IFNULL((CASE
            WHEN
                `jp`.`account_manager_id` IS NULL
                    OR `jp`.`account_manager_id` = 0
            THEN
                (SELECT 
                        (CASE
                                WHEN
                                    account_manager_id IS NULL
                                        OR account_manager_id = 0
                                THEN
                                    `u`.`account_manager_id`
                                ELSE account_manager_id
                            END) AS account_manager_id
                    FROM
                        user_user
                    WHERE
                        id = (SELECT 
                                user_id
                            FROM
                                game_user_assigned
                            WHERE
                                game_id = `jp`.`id`
                            LIMIT 1))
            ELSE `jp`.`account_manager_id`
        END),
        `u`.`account_manager_id`) AS acc,
(SELECT 
        COUNT(recach_limit_id)
    FROM
        recach_limit
    WHERE
        recach_limit = '1'
            AND recach_limit_game_id = rpr.recach_limit_game_id) AS somewhatgame,
(SELECT 
        COUNT(recach_limit_id)
    FROM
        recach_limit
    WHERE
        recach_limit = '2'
            AND recach_limit_game_id = rpr.recach_limit_game_id) AS verygamecommitted,
(SELECT 
        COUNT(recach_limit_id)
    FROM
        recach_limit
    WHERE
        recach_limit = '3'
            AND recach_limit_game_id = rpr.recach_limit_game_id) AS notgame,
(SELECT 
        COUNT(joa.id) AS applicationcount
    FROM
        game_refer_to_member jrmm
            INNER JOIN
        game_refer jrr ON jrr.id = jrmm.rid
            INNER JOIN
        game_applied joa ON jrmm.id = joa.referred_by
    WHERE
        jrmm.STATUS = '1'
            AND jrr.referby_user_id IN (SELECT 
                ab_testing_user_id
            FROM
                ab_testing)
            AND joa.game_post_id = rpr.recach_limit_game_id
            AND (rpr.recach_limit = 1
            OR rpr.recach_limit = 2)) AS gamecount
 FROM
(`game_post` AS jp)
    JOIN
`user_info` AS u ON `jp`.`user_user_id` = `u`.`id`
    JOIN
`game_functional` jf ON `jp`.`game_functional_id` = `jf`.`id`
    LEFT JOIN
`group_musesm` gm ON `gm`.`group_id` = `jp`.`group_id`
    LEFT JOIN
`recach_limit` rpr ON `jp`.`id` = `rpr`.`recach_limit_game_id`
 WHERE
`jp`.`status` != '3'
 GROUP BY `jp`.`id`
 ORDER BY `posted_on` DESC
 LIMIT 10

2 个答案:

答案 0 :(得分:0)

我首先建议不要嵌套select语句,因为这会导致每个xth级别的n ^ x性能命中,并且我在此查询中看到至少3个选择级别。

答案 1 :(得分:0)

添加索引

INDEX(status, posted_on)

将LIMIT移到

然后,而不是说

FROM  (`game_post` AS jp)

FROM ( SELECT id FROM game_post
           WHERE status != 3
           ORDER BY posted_on DESC
           LIMIT 10 ) AS ids
JOIN game_post AS jp  USING(id)

(我假设jp的PK是(id)?)

这应该有效地使用新索引来获得所需的10个ID。然后它将返回到game_post以获取其他列。

<强> LEFT

此外,除非您需要,否则不要说LEFT。生成您可能不需要的NULLs会花费一些成本。

GROUP BY是否必要?

如果删除GROUP BY,是否显示重复ID?上述变更可能已经消除了这种需求。

IN(SELECT)可能会很差地优化

更改

AND  jrr.referby_user_id IN ( SELECT  ab_testing_user_id
                               FROM  ab_testing )

AND   EXISTS ( SELECT * FROM ab_testing
                      WHERE ab_testing_user_id = jrr.referby_user_id )

(此更改可能会有所帮助,也可能没有帮助,具体取决于您运行的版本。)

更多

如果您需要进一步的帮助,请提供EXPLAIN SELECT