所以我有这个查询
SELECT a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`,
(SELECT COUNT(id) FROM `Release` r WHERE r.`article_id`=a.`id`) AS `num_rows`,
(SELECT COUNT(id) FROM `Article_views` av WHERE av.`article_id`=a.`id`) AS `num_rows2`
FROM `Article` a WHERE a.`type` = 'ani' ORDER BY a.`title` ASC
第一次加载最多需要5秒,如果我进行刷新,大约需要0.001秒,有办法统一加载时间吗?
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY a ALL NULL NULL NULL NULL 567 Using where; Using filesort
3 DEPENDENT SUBQUERY av ALL NULL NULL NULL NULL 5301 Using where
2 DEPENDENT SUBQUERY r ALL NULL NULL NULL NULL 11717 Using where
我试着用join来做,但根本不起作用,所以我放弃了这种方式。。。
解决方案
使用barmar查询。更好的方法:)(和索引-,-')
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 536 Using temporary; Using filesort
1 PRIMARY a eq_ref PRIMARY PRIMARY 4 r.art.. 1 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 574 Using where; Using join buffer
3 DERIVED Article_views index NULL article_id 4 NULL 5301 Using index
2 DERIVED Release index NULL article_id 4 NULL 11717 Using index
感谢大家的时间和解决方案:)我想我需要重做这个旧项目的一个好部分ahah:)
改为尝试此查询:
SELECT a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`, `num_rows`, `num_rows2`
FROM `Article` a
JOIN (SELECT article_id, COUNT(*) AS num_rows
FROM Release
GROUP BY article_id) r
ON r.article_id = a.id
JOIN (SELECT article_id, COUNT(*) AS num_rows2
FROM Article_views
GROUP BY article_id) av
ON av.article_id = a.id
WHERE a.`type` = 'ani'
ORDER BY a.`title` ASC
根据我的经验,JOIN比相关的子查询更快。
为了提高性能,请确保在Release.article_id
和Article_views.article_id
上有索引。
我想,第二次尝试是SQL QUERY CACHE
的好处。我想知道添加SQL_NO_CACHE
,每次尝试是否需要5秒?
SELECT SQL_NO_CACHE a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`,
....
索引
哎呀。您没有相关的INDEX。你能添加以下索引吗?
ALTER TABLE Article ADD INDEX(type);
ALTER TABLE Release ADD INDEX(article_id);
ALTER TABLE Article_views ADD INDEX(article_id);
更高效的查询
您的查询转换为JOIN
。我想这比你的快多了。假设每个Article
都有Release
和Article_views
SELECT a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`,
COUNT(r.id) AS `num_rows`,
COUNT(av.id) AS `num_rows2`
FROM `Article` a JOIN Release r ON r.`article_id`=a.`id`
JOIN Article_views av ON av.`article_id`=a.`id`
WHERE a.`type` = 'ani'
GROUP BY a.title, a.id, a.numvol, a.numepi, a.release_date
ORDER BY a.`title` ASC;
查询延迟的显著改善是由于内部MySQL缓存的功能。
在查询的第一次执行之后,结果集被缓存在RAM中,因此在没有HDD访问的情况下,立即从RAM中获取与前一次匹配的第二次查询的结果。
关于MySQL内部缓存有不同的观点,专家们经常建议在高负载的生产环境中使用memecached、Redis或其他缓存层来禁用它。
但您肯定应该尝试在关闭缓存的情况下优化查询的性能——5秒非常慢。
- 尽量不要使用子查询,因为MySQL优化器对它们没有性能
- 将计数器的值(
count()
的结果)存储在单独的表中,并正确更新它们。然后,您可以在查询中只使用计数器值,而无需每次都执行繁重的数据库请求 - 例如,为
type
字段创建索引 - 使用
EXPLAIN
进行进一步优化