我在MySQL中的一个查询在执行时花费了太多时间。在此查询中,我使用 IN 运算符从 MySQL 数据库获取数据库。
我的查询 :
SELECT *
FROM databse_posts.post_feeds
WHERE
post_id IN (SELECT post_id FROM database_users.user_bookmarks where user_id=3) AND
post_date < unix_timestamp();
在这种情况下,两个单独的查询执行时间都非常少,例如
SELECT post_id FROM database_users.user_bookmarks where user_id=3
最多需要大约 400 毫秒
和
SELECT * FROM databse_posts.post_feeds Where post_date < unix_timestamp();
最多需要 300 毫秒
但是使用 IN 运算符将两个查询合并为一个查询大约需要 6 到 7 秒。 为什么这需要太多时间。 我还编写了不同类型的查询,但所有这些查询都不会花费那么多时间。
而不是 where IN(子选择(,您可以在子选择上尝试内部联接
SELECT *
FROM databse_posts.post_feeds
INNER JOIN (
SELECT post_id
FROM database_users.user_bookmarks
where user_id=3
) T on T.post_id = post_feeds.post_id
AND
post_date < unix_timestamp();
并确保您对post_feeds.post_id
和user_bookmarks.user_id, user_bookmarks.post_id
有适当的索引
我的方法:
您需要为字段创建索引post_feeds
。post_id
,user_bookmarks
.post_id
,user_bookmarks
。user_id
和post_feeds
.post_date
字段,然后使用INNER JOIN让MySQL引擎以有效的方式操作行的过滤和合并:
SELECT
pf.*
FROM
databse_posts.post_feeds pf
INNER JOIN database_users.user_bookmarks ub
ON ( pf.post_id = ub.post_id )
WHERE
ub.user_id = 3
AND pf.post_date < unix_timestamp();
我在这里的粗略猜测是,WHERE IN
表达式正在做一些你可能不知道的事情。 考虑您的完整查询:
SELECT *
FROM databse_posts.post_feeds
WHERE
post_id IN (SELECT post_id FROM database_users.user_bookmarks where user_id=3) AND
post_date < unix_timestamp();
MySQL必须检查每条记录的每个post_id
值,并将其与来自子查询的post_id
列表进行比较。 这比只运行一次该子查询的成本要高得多。 MySQL可以使用各种技巧来加快速度,但是WHERE IN
子句中的子查询与仅运行一次该子查询不同。
如果此假设正确,则以下查询也应在 6-7 秒的范围内:
SELECT *
FROM databse_posts.post_feeds
WHERE
post_id IN (SELECT post_id FROM database_users.user_bookmarks where user_id=3)
如果是这样,那么我们就会知道性能缓慢的根源。