[英]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。
现在,您确定了导致性能下降的查询。 让我们尝试对其进行调整。
尝试这两个查询,因为它们应该可以帮助您提高速度。
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
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)
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.