我正在使用MySQL在wiki上构建一个正向索引。我在查询中遇到了性能问题,我希望能够帮助优化我的模式或查询。
数据库大约是1GB,它有三个表。
fi\_keyword ( id int(11) NOT NULL AUTO_INCREMENT,keyword varchar(100) NULL,PRIMARY KEY (id),UNIQUE KEY keyword (keyword) );fi\_titlekeywordlink ( id int(11) NOT AUTO_INCREMENT,keyword\_id int(11) NULL,page\_id int(11) NULL,主键(id),密钥fi\_titlekeywordlink\_a6434082 (keyword\_id),密钥fi\_titlekeywordlink\_c2d3d2bb (page\_id),约束<代码>D21外键(<id>D22)引用<id>D23(<id>D24),约束<代码>D25外键(page\_id)引用fi\_page (id );我正在将搜索“搜索术语”转换为sql查询,如
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上。谢谢。
发布于 2012-05-10 14:13:24
以插入性能为代价,您可以从两个表中删除代理id主键列,并使keyword列上的主键索引用于fi_keyword和(keyword_id,page_id)作为fi_titlekeywordlink的主键索引。
如果使用InnoDB,主键是聚集索引,因此它们要快得多。
即使不进行此更改,(keyword_id,page_id)在fi_titlekeywordlink上的复合(多列)索引也会提高性能,因为在fi_titlekeywordlink上有一个覆盖索引(MySQL不必访问表数据)。这假设您的MySQL服务器有足够的RAM来容纳内存中的所有索引,并且您已经配置了MySQL服务器以允许它使用足够的RAM来实现这一点( MyISAM和InnoDB之间的配置变量不同)。
有时,隐式连接会变得过于复杂,以致于MySQL无法进行适当的优化。您还应该考虑使用JOIN和ON使用显式ANSI标准联接重写查询。
您可能只是为简洁性编写了SELECT p.*,但请确保只选择所需的列,这样就不会返回不需要的数据。只有返回所需的列才能减少工作负载。
此外,限制子句中的第一行为0,因此LIMIT 1, 10跳过第一行。使用LIMIT 0, 10获取前10行。
https://stackoverflow.com/questions/10535575
复制相似问题