我的SQL运行需要40秒,而PHP执行同样的操作要快得多。为什么呢?
我有以下SQL:我的SQL运行需要40秒,而PHP执行同样的操作要快得多。为什么呢?,php,mysql,sql,Php,Mysql,Sql,我有以下SQL: SELECT t1.thread,t1.sender,t1.recipient,t1.subject, (SELECT COUNT(*) FROM `student-messages-seen` WHERE messageID = t1.id) AS count, (SELECT id FROM `student-messages-seen` WHERE messageID = (SELECT MAX(id) FROM `student-mess
SELECT t1.thread,t1.sender,t1.recipient,t1.subject,
(SELECT COUNT(*) FROM `student-messages-seen` WHERE messageID = t1.id) AS count,
(SELECT id FROM `student-messages-seen` WHERE messageID = (SELECT MAX(id) FROM `student-messages` t3 WHERE t3.thread = t1.thread) AND userID = 4) AS seen,
(SELECT ts FROM `student-messages` WHERE thread = t1.thread ORDER BY ID DESC LIMIT 1) AS ts
FROM `student-messages` t1
WHERE (sender = 4 OR recipient = 4)
AND id = (SELECT MIN(id) FROM `student-messages` WHERE thread = t1.thread)
GROUP BY thread ORDER BY ts DESC
有两个表,学生信息
和学生信息。如果有必要,我可以发布表格的结构
上面的SQL语句需要40秒(!)才能运行!我知道里面有一堆嵌入的语句,但这真的太长了
我需要了解的是:
为什么要花这么长时间
如果我用PHP单独编写语句,整个过程会快得多。为什么呢
我怎样才能加快这个过程
这是一个使用至少5个子查询集的查询,它是复杂的;)
我可以保证,此查询速度慢的原因与索引有关!请确保为每个子查询设置了正确的索引。通过在表中设置索引,您将提高性能
如果您使用的是MYSQL,那么可以使用EXPLAIN来获取有关索引的更多信息
EXPLAIN SELECT
t1.thread,
t1.sender,
t1.recipient,
t1.subject,
(SELECT COUNT(*) FROM `student-messages-seen` WHERE messageID = t1.id) AS count,
(SELECT id FROM `student-messages-seen` WHERE messageID = (SELECT MAX(id) FROM `student-messages` t3 WHERE t3.thread = t1.thread) AND userID = 4) AS seen,
(SELECT ts FROM `student-messages` WHERE thread = t1.thread ORDER BY ID DESC LIMIT 1) AS ts
FROM `student-messages` t1
WHERE (sender = 4 OR recipient = 4)
AND id = (SELECT MIN(id) FROM `student-messages` WHERE thread = t1.thread)
GROUP BY thread ORDER BY ts DESC
需要确保此表具有索引集:
表格学生信息
列发送器的索引
列收件人的索引
列线程的索引
查看学生信息表
列messageID的索引
列messageID+列userID的索引这是一个使用至少5个子查询集的查询,它是复杂的;)
我可以保证,此查询速度慢的原因与索引有关!请确保为每个子查询设置了正确的索引。通过在表中设置索引,您将提高性能
如果您使用的是MYSQL,那么可以使用EXPLAIN来获取有关索引的更多信息
EXPLAIN SELECT
t1.thread,
t1.sender,
t1.recipient,
t1.subject,
(SELECT COUNT(*) FROM `student-messages-seen` WHERE messageID = t1.id) AS count,
(SELECT id FROM `student-messages-seen` WHERE messageID = (SELECT MAX(id) FROM `student-messages` t3 WHERE t3.thread = t1.thread) AND userID = 4) AS seen,
(SELECT ts FROM `student-messages` WHERE thread = t1.thread ORDER BY ID DESC LIMIT 1) AS ts
FROM `student-messages` t1
WHERE (sender = 4 OR recipient = 4)
AND id = (SELECT MIN(id) FROM `student-messages` WHERE thread = t1.thread)
GROUP BY thread ORDER BY ts DESC
需要确保此表具有索引集:
表格学生信息
列发送器的索引
列收件人的索引
列线程的索引
查看学生信息表
列messageID的索引
列messageID+列userID的索引使用正确的索引并写入正确的联接。也可以考虑使用CTE @ KPassFi火,那么什么是“正确”连接?如果我做错了,请写一个答案来纠正我。。。我不会为你写完整的问题,但你应该解释一下你到底想实现什么?看起来您正在论坛中寻找最新的帖子不要在查询中获取最新的时间戳,而是使用聚合函数MAX,因为您已经在分组。。。您选择/分组的每一列都应该是一个索引。。。在您的示例中,student-messages.thread和student-messages-seen.messageID应该是一个indexSample数据、所需结果和逻辑解释将非常有用。使用正确的索引并编写正确的联接。也可以考虑使用CTE @ KPassFi火,那么什么是“正确”连接?如果我做错了,请写一个答案来纠正我。。。我不会为你写完整的问题,但你应该解释一下你到底想实现什么?看起来您正在论坛中寻找最新的帖子不要在查询中获取最新的时间戳,而是使用聚合函数MAX,因为您已经在分组。。。您选择/分组的每一列都应该是一个索引。。。在您的例子中,student-messages.thread和student-messages-seen.messageID应该是一个indexSample数据、期望的结果以及对逻辑的解释都非常有用。哇!非常感谢。今天之前我从未使用过索引,我只是看了一个视频:它很好地解释了一切。由于您告诉我要创建的索引,查询现在需要0.0053秒。您是如何决定使用哪些索引的?Cool@Chud37:),很高兴您解决了这个问题。是否需要索引取决于表项。如果一个表的条目少于500个,则可能不需要索引。如果您假设一个表的条目数将超过创建它们所需的500个。。。在使用WHERE或AND等表示该子句的查询语句中,您需要索引。。。我只是分析了使用where、AND或的查询,并确定了哪些列需要索引集。我还认为YouTube上有一些非常好的视频,它们非常棒。哇!非常感谢。今天之前我从未使用过索引,我只是看了一个视频:它很好地解释了一切。由于您告诉我要创建的索引,查询现在需要0.0053秒。您是如何决定使用哪些索引的?Cool@Chud37:),很高兴您解决了这个问题。是否需要索引取决于表项。如果一个表的条目少于500个,则可能不需要索引。如果您假设一个表的条目数将超过创建它们所需的500个。。。在使用WHERE或AND等表示该子句的查询语句中,您需要索引。。。我只是分析了使用where、AND或的查询,并确定了哪些列需要索引集。我还认为YouTube上有一些非常好的视频,它们非常好。