繁体   English   中英

SQL查询性能问题全表扫描

[英]SQL query performance issue full table scan

我有一个触发以下sql的脚本。 到目前为止,该查询的性能还不错,我相信这是因为其中一个表中存在大量记录,并且根据我正在查询中运行的解释,它正在针对该表进行扫描整个用户表(大约一千万条记录)。

有没有更好的方法可以编写此代码,使其不扫描,并且我可以将执行时间降低到<1秒?

SELECT 
`users` . *,
users.username AS `fullname`,
(SELECT 
        CONCAT_WS('|||',
                    image,
                    width,
                    height,
                    original,
                    mime)
    FROM
        `users_avatars`
    WHERE
        (user_id = users.user_id)
            AND (size = '_A')
    LIMIT 1) AS `user_avatar_a`,
(SELECT 
        CONCAT_WS('|||',
                    image,
                    width,
                    height,
                    original,
                    mime)
    FROM
        `users_avatars`
    WHERE
        (user_id = users.user_id)
            AND (size = '_B')
    LIMIT 1) AS `user_avatar_b`,
(SELECT 
        CONCAT_WS('|||',
                    image,
                    width,
                    height,
                    original,
                    mime)
    FROM
        `users_avatars`
    WHERE
        (user_id = users.user_id)
            AND (size = '_C')
    LIMIT 1) AS `user_avatar_c`,
((SELECT 
        COUNT(ufu_id)
    FROM
        `users_following_user`
    WHERE
        (user_id = 684767)
            AND (following_id = users.user_id)
    LIMIT 1) + (SELECT 
        COUNT(users_following_id)
    FROM
        `users_following`
    WHERE
        (user_id = 684767)
            AND (following_id = users.user_id)
    LIMIT 1)) AS `following_user`
FROM
`users`
WHERE
(users.user_id IN ((SELECT 
        `users_boards`.`user_id`
    FROM
        `users_boards`
    WHERE
        (board_id = '353048') AND (allow = 1))))

****更新****我相信我已经隔离,或者至少缩小了问题的出处。

SELECT *
FROM
    `users`
WHERE
    (users.user_id IN ((SELECT 
        `users_boards`.`user_id`
    FROM
        `users_boards`
    WHERE
        (board_id = '353048') AND (allow = 1))))

对查询的解释给出以下内容:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1, PRIMARY, users, ALL, PRIMARY, , , , 3952473, 100.00, 
1, PRIMARY, users_boards, ref, user_id, user_id, 16, skoovy_prd.users.user_id,const, 1, 100.00, Using where; FirstMatch(users)

首先,您应该考虑在子查询上使用JOIN。 除非您有充分的理由使用子查询,否则这本身应该显示出性能的提高。 我无法想象有一个很好的理由会阻止您使用JOINS。

现在,您确定了导致性能下降的查询。 让我们尝试对其进行调整。

尝试这两个查询,因为它们应该可以帮助您提高速度。

1如果用户和users_board之间的关系是1:1,并且您要显示所有结果,请加入查询

SELECT su.* FROM users AS su
INNER JOIN users_boards AS b ON b.user_id = su.user_id
WHERE b.board_id = 353048 AND b.allow = 1

2个EXISTS()子查询。 如果users表和user_board之间的关系为1:many,则此查询应该是一个简短而快速的电路

SELECT *
FROM users AS su
WHERE EXISTS (SELECT 1 FROM users_boards WHERE user_id = su.user_id AND board_id = 353048 AND allow = 1)

3您可以在上面列出的任何查询之前尝试使用临时表,以查看是否有任何改进。

CREATE TEMPORARY TABLE users_boards (KEY(user_id)) ENGINE=MEMORY AS
SELECT user_id
FROM users_boards
WHERE user_id = su.user_id AND board_id = 353048 AND allow = 1;

同样,该索引应该非常有帮助。 如果可以添加(如果不存在),则应考虑

ALTER TABLE users_boards ADD INDEX combo (user_id, board_id, allow);

如果这样做没有帮助,您应该考虑为用户和users_boards发布show create table ,我想您的列类型是不同的。

SHOW CREATE TABLE users;
SHOW CREATE TABLE users_board;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM