MySQL查询运行时间> 15秒;我该怎么做才能缓存/改进它?

时间:2008-12-06 21:49:40

标签: php mysql caching

我有一个视频网站,其中一些表格是:

代码

id ~ int(11), auto-increment [PRIMARY KEY]
tag_name ~ varchar(255)

videotags

tag_id ~ int(11) [PRIMARY KEY]
video_id ~ int(11) [PRIMARY KEY]

视频

id ~ int(11), auto-increment [PRIMARY KEY]
video_name ~ varchar(255)

现在,此时标签表具有> 1000行,而视频标签表具有> 32000行。因此,当我运行查询以显示从最常见到最不常见的所有标记时,执行时需要> 15秒。

我正在使用PHP和我的代码(为简单而淡化)如下:

foreach ($database->query("SELECT tag_name,COUNT(tag_id) AS 'tag_count' FROM tags LEFT OUTER JOIN videotags ON tags.id=videotags.tag_id GROUP BY tags.id ORDER BY tag_count DESC") as $tags)
{
    echo $tags["tag_name"] . ', ';
}

现在请记住,这是100%准确对我来说并不像快速那么重要。因此,即使查询每天执行一次并且其结果在当天的剩余时间内使用,我也不在乎。

我对MySQL / PHP缓存一无所知所以请帮助!

4 个答案:

答案 0 :(得分:3)

MarkR提到了索引。请确保:

create index videotags_tag_id on videotags(tag_id);

答案 1 :(得分:2)

32,000行仍然是一张小桌子 - 你的表现不可能那么糟糕。

你可以在你的查询上运行EXPLAIN - 我猜你的索引在某处错了。

你在问题​​中说:

tag_id ~ int(11) [PRIMARY KEY]
video_id ~ int(11) [PRIMARY KEY]

他们肯定是那个顺序吗?如果没有,那么它将不会使用索引。

答案 2 :(得分:0)

我认为最好的办法是创建一些汇总表,并在事情发生变化时进行维护。

上面的查询需要扫描表中的所有行,以便通过以下方式查找聚合: - 没有WHERE CLAUSE。没有where子句的查询没有优化的希望,因为它必须检查每一行。

修复方法是创建一个摘要表,其中包含与该查询(或类似)结果相同的数据,当数据发生变化或发生显着变化时,您将不得不维护这些数据。

只有您可以根据应用程序和数据的性质决定是否适合按计划,每次更新或某种组合更新摘要表。

当你正在进行连接时,正确的索引仍然是有益的,但你知道,对,并且已经完成了吗?

答案 3 :(得分:0)

您使用的是InnoDB还是MyISAM?在MyISAM中COUNT基本上是免费的,但在InnoDB中它必须实际计算行数。