首先我们的环境是PHP+MYSQL。 我们有一个表Articles,它是用来保存文本文章的表。大约有15000条记录。 我们在查询中遇到性能问题:
SELECT article_id, article_title, article_status,
article_date_time, article_publish_date
FROM articles
WHERE article_status IN ('approved')
AND (article_publish_date <= now())
AND ((article_expiry_date = '0000-00-00') OR
(article_expiry_date <> '0000-00-00'
AND article_expiry_date >= now()))
AND articles_id IN (1, 2, 3... a list of about 9,000 possible ID's)
GROUP BY article_id
ORDER BY article_date_time DESC LIMIT 0,5;
在我们的测试站点(数据库服务器和网络服务器在同一台机器上),如果我第一次运行查询,查询的执行时间约为 30 秒。 还是在测试站点,如果我只是刷新页面第二次运行查询,查询的执行时间约为0.2秒。
如果一直刷新,执行时间还是0.2秒左右。但是如果我停止大约 15 分钟,执行时间将再次变为 30 秒,然后是 0.2 秒...
问题 1 来了:第一次执行和第二次执行之间的巨大差异是什么?缓存?如果是这样,那么它是如何产生影响的?
仍然是相同的查询,在我们的实时站点中(仍然,数据库服务器和 Web 服务器在同一台机器上),查询的执行时间约为 3 秒。但无论您运行查询多少次,时间都在 3 秒左右。
test db是live db的备份,所以db的差异不应该造成如此不同的结果。
问题 2 来了:为什么实时站点的执行时间不是 30 秒也不是 0.2 秒?为什么它不会在第二次执行时发生变化?
有人可以帮忙吗?
最佳答案
与其回答为什么它在两台服务器上以不同的时间运行的问题,我认为首先尝试优化您的查询很重要。
首先,您需要避免使用 IN
运算符使用大量文字。
我建议添加另一个字段
指示此 in
操作的结果:
ALTER TABLE articles ADD (
flag int
);
UPDATE articles
SET article_flag =
CASE
WHEN article_id IN (1, 2, 3... a list of about 9,000 possible IDs) THEN 1
ELSE 0
END;
COMMIT;
如果尚未完成,请确保在 article_date_time
上建立索引:
CREATE INDEX idx_article_date_time ON articles(article_date_time);
然后在不使用 group by
和少一个冗余条件的情况下使用此查询:
SELECT article_id, article_title, article_status,
article_date_time, article_publish_date
FROM articles
WHERE article_status = 'approved'
article_flag = 1
AND article_publish_date <= now()
AND ( article_expiry_date = '0000-00-00'
OR article_expiry_date >= now()
)
ORDER BY article_date_time DESC LIMIT 0,5;
如果您执行所有这些操作,我预计性能会有所提高。
关于php - 查询的性能差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33481370/