gpt4 book ai didi

mysql - 两个 SQL 查询 - 性能差异?

转载 作者:行者123 更新时间:2023-11-29 04:23:07 26 4
gpt4 key购买 nike

我在 PHP 中使用带有 PDO 的 MySQL 并且我有一个 SQL 查询,它按预期工作。但是,我关心性能并且想知道我是否可以改进我的查询。我也在问,因为我想获得一些SQL背景知识

假设我有两个表,它们有几个相同的字段(以及一些附加信息,它们在每个表中都不同):

table `blog_comments`: id, userid (int) | timestamp (int) | content (varchar) | other
table `projects_comments`: id, userid (int) | timestamp (int) | content (varchar) | other

字段id主键userid + timestamp在两个表中都有一个索引,并且timestamp 就是长度为 10(整数)的 unixtime。

作为简单的垃圾邮件保护,我会阻止用户提交新评论(无论是博客、项目还是其他任何内容),直到他上次评论后 60 秒。为实现这一点,我从所有评论表中获取该用户的最新时间戳

这是我的工作查询:

SELECT MAX(`last_timestamp`) AS `last_timestamp`
FROM
(
SELECT `userid`, max(`timestamp`) AS `last_timestamp`
FROM `blog_comments`
GROUP BY `userid`
UNION ALL
SELECT `userid`, max(`timestamp`) as `last_timestamp`
FROM `projects_comments`
GROUP BY `userid`
) AS `subquery`
WHERE `userid` = 1
LIMIT 0, 1;

如您所见,我在子查询中使用GROUP BY,而在主查询中我只是过滤 userid(在本例中:1)。优点:我只需要将 userid 一次作为参数传递

现在,我对 SQL 的确切工作原理很感兴趣。我认为它会是这样的:SQL 首先执行子查询,将 所有 现有行 按 userid 分组,然后返回整个集合 到主查询,然后应用 where 子句来查找所需的用户标识。这对我来说似乎是一个很大的性能泄漏。

所以我考虑稍微更改查询:

SELECT max(`last_timestamp`) AS `last_timestamp`
FROM
(
SELECT max(`timestamp`) AS `last_timestamp`
FROM `blog_comments`
WHERE `userid` = 1
UNION ALL
SELECT max(`timestamp`) as `last_timestamp`
FROM `projects_comments`
WHERE `userid` = 1
) AS `subquery`
LIMIT 0, 1

现在我必须传递用户 ID 两次,仍然会为给定的用户 ID 查找整组行。我不确定这是否真的改善性能。

我目前还没有大数据量去真正测试它,也许以后会做一些测试场景。我真的很想知道这些表中何时会有很多数据集是否会有所不同?

如果有任何想法、信息和提示,请提前致谢。

编辑:

第一个查询的MySQL解释:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using where
2 DERIVED blog_comments range NULL userid 8 NULL 10 Using index for group-by
3 UNION projects_comments index NULL userid 12 NULL 6 Using index
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL

second 查询的 MySQL 解释:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
3 UNION NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL

最佳答案

作为替代方法...

SELECT 'It''s been more than 1 minute since your last post' As result
WHERE NOT EXISTS (
SELECT *
FROM blog_comments
WHERE userid = 1
AND timestamp > Date_Sub(Current_Timestamp, INTERVAL 1 MINUTE)
)
AND NOT EXISTS (
SELECT *
FROM projects_comments
WHERE userid = 1
AND timestamp > Date_Sub(Current_Timestamp, INTERVAL 1 MINUTE)
)

如果 userid = 1 在任何一个表中的最后一分钟内都没有时间戳记录,将会有一个结果。

您还可以交换逻辑...

SELECT 'You''re not allowed to post just yet...' As result
WHERE EXISTS (
SELECT *
FROM blog_comments
WHERE userid = 1
AND timestamp > Date_Sub(Current_Timestamp, INTERVAL 1 MINUTE)
)
OR EXISTS (
SELECT *
FROM projects_comments
WHERE userid = 1
AND timestamp > Date_Sub(Current_Timestamp, INTERVAL 1 MINUTE)
)

第二个选项可能会更有效(EXISTS vs NOT EXISTS),但这需要您进行测试和证明;)

关于mysql - 两个 SQL 查询 - 性能差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17945161/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com