我运行的网站有大量搜索功能。这些搜索非常重要,并且需要连接到结果的多个数据。
我的解决方案是将搜索结果存储在两个表中:搜索和搜索结果
搜索包含搜索的元数据
Searchresults包含两列idsearch,iddata并且是一个内存表
为了防止搜索结果的内存溢出,我们会定期修剪此表并刷新过时的数据。据我所知,内存表具有表级锁定功能,因此在修剪过程中,searchresults表会被阻塞并导致站点性能下降。
解决方案是为每个搜索创建一个新表,然后在搜索失效时删除此searchresults_xxxx表。
我这样做是首先删除搜索表中的旧陈旧条目。然后执行以下操作:
select table_name
from information_schema.tables
where
table_schema = 'mysite_datawarehouse'
and table_name not in (select concat('searchresults_', idsearch) from searches);
经常有成千上万的匹配,导致平均查询时间约为30秒左右。在此期间,性能再次降低,我又回到原点。有没有更好的方法来写这个?或者也许是一种更好的方法来构建这个?
谢谢!
答案 0 :(得分:0)
我刚刚问过并解决了相关问:Slow query on information_schema.tables。您在这里遇到的问题是查询将通过对* .FRM文件进行目录扫描来枚举数据目录中的所有表。它还可以打开每个FRM文件并读取其标题。这会很慢。
我的Q是为什么要查询信息模式?我假设您信任搜索内容。为什么不在搜索中包含创建时间戳字段,并选择创建rimestamp早于特定年龄的所有表名。如果然后直接执行循环,如果存在则执行drop table,甚至将此清理过程移动到存储过程中。对信息模式执行主查询不会增加任何内容并减慢剪枝过程的速度。
答案 1 :(得分:0)
这是原始查询
select table_name
from information_schema.tables
where
table_schema = 'mysite_datawarehouse'
and table_name not in
(select concat('searchresults_', idsearch) from searches);
如果有很多InnoDB表可以浏览
,我很容易发现它会很慢尝试重构查询查询以执行LEFT JOIN,如下所示:
select A.table_name
from (select concat('searchresults_', idsearch) table_name from searches) A
LEFT JOIN
(select table_name FROM information_schema.tables
where table_schema = 'mysite_datawarehouse') B
USING (table_name)
WHERE B.table_name IS NULL;