优化MySQL中的正向索引
我正在使用MySQL在wiki上构建正向索引。我在查询中遇到了性能问题,我希望在优化我的模式或查询时得到一些帮助 数据库大约1GB,有三个表优化MySQL中的正向索引,mysql,sql,database,query-optimization,Mysql,Sql,Database,Query Optimization,我正在使用MySQL在wiki上构建正向索引。我在查询中遇到了性能问题,我希望在优化我的模式或查询时得到一些帮助 数据库大约1GB,有三个表 fi_页面是800k wiki页面的表格 fi_关键字是一个包含70k个关键字的表 CREATE TABLE `fi_keyword` ( `id` int(11) NOT NULL AUTO_INCREMENT, `keyword` varchar(100) NOT NULL, PRIMARY KEY (`id`), U
- fi_页面是800k wiki页面的表格
- fi_关键字是一个包含70k个关键字的表
CREATE TABLE `fi_keyword` ( `id` int(11) NOT NULL AUTO_INCREMENT, `keyword` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `keyword` (`keyword`) );
- fi_titlekeywordlink是一个包含600万条目的表,将关键字链接到wiki页面
CREATE TABLE `fi_titlekeywordlink` ( `id` int(11) NOT NULL AUTO_INCREMENT, `keyword_id` int(11) NOT NULL, `page_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `fi_titlekeywordlink_a6434082` (`keyword_id`), KEY `fi_titlekeywordlink_c2d3d2bb` (`page_id`), CONSTRAINT `keyword_id_refs_id_67197756` FOREIGN KEY (`keyword_id`) REFERENCES `fi_keyword` (`id`), CONSTRAINT `paper_id_refs_id_705ddf03` FOREIGN KEY (`page_id`) REFERENCES `fi_page` (`id`) );
select p.*
from
fi_keyword as k0, fi_titlekeywordlink as l0,
fi_keyword as k1, fi_titlekeywordlink as l1,
fi_keyword as k2, fi_titlekeywordlink as l2,
fi_keyword as k3, fi_titlekeywordlink as l3,
fi_page as p
where
k0.keyword = e and k0.id = l0.keyword_id and p.id = l0.paper_id
and k1.keyword = 'search' and k1.id = l1.keyword_id and p.id = l1.paper_id
and k2.keyword = 'terms' and k2.id = l2.keyword_id and p.id = l2.paper_id
and k3.keyword = 'galore' and k3.id = l3.keyword_id and p.id = l3.paper_id
limit 1,10
然而,在我的MBP上运行大约需要半秒钟。对于如何通过更改模式或查询来加速此类操作,您有什么建议吗?在这种情况下,我不能使用单独的搜索服务器,转发索引必须在MySQL上运行。谢谢。以插入性能为代价,您可以从两个表中删除代理
id
主键列,并在关键字
列上为fi_关键字建立主键索引,并(关键字
,页面id
)作为fi_titlekeywordlink的主键索引
如果您使用的是InnoDB,主键是聚集索引,因此它们的速度要快得多
即使您不做此更改,fi_titlekeywordlink上(关键字id
,页面id
)的复合(多列)索引也会提高性能,因为fi_titlekeywordlink上有一个覆盖索引(MySQL不必访问表数据)。这假设您的MySQL服务器有足够的RAM来容纳内存中的所有索引,并且您已经配置了MySQL服务器,以允许它使用足够的RAM(配置变量在和之间不同)
有时,隐式连接会变得太复杂,MySQL无法正确优化。您还应该考虑使用“代码> >连接< /代码>和<代码>在 < /P>中重写该查询。
为了简洁起见,您可能刚刚编写了SELECT p.*
,但请确保只选择所需的列,这样就不会返回不需要的数据。只返回所需的列可以减少工作量
此外,LIMIT子句中的第一行是0,因此
LIMIT 1,10
跳过第一行。使用LIMIT 0,10
获得前10行。@MarcusAdams是的,但我很高兴改变这一点。感谢您的快速响应,我将处理这些建议。我添加了一个复合索引,并切换到ansi连接语法,这对我很有帮助。弄清楚如何更改主键需要一点时间,但我也会这么做。谢谢你的帮助。