优化MySQL中的正向索引

优化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

我正在使用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`),  
      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`)
    );
    
我正在将对“搜索词”的搜索转换为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上运行。谢谢。

以插入性能为代价,您可以从两个表中删除代理
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连接语法,这对我很有帮助。弄清楚如何更改主键需要一点时间,但我也会这么做。谢谢你的帮助。