2008-09-06 85 views
9

我有一个webapp开发问题,我已经开发了一个解决方案,但我试图找到其他想法来解决一些性能问题。操作方法:排名搜索结果

问题陈述:

  • 用户输入几个关键字/令牌
  • 用于匹配的应用程序搜索到令牌
  • 需要一个结果,每个令牌
    • 也就是说,如果一个条目有3个代币,我需要入场证3次
  • ran k为结果
    • 为x点记号匹配
    • 排序基于分项IDS
    • 如果点值是相同的,使用日期排序结果

我希望能够做但尚未想出发送1查询返回类似于in()的结果的内容,但是为每个标记匹配的每个条目标识符检查返回一个重复的条目标识符。

有没有更好的方法来做到这一点比我在做什么,使用多个单个查询每个令牌运行一个查询?如果是这样,那么实现这些最简单的方法是什么?

编辑
我已经符号化的条目,因此,例如,“看到现场运行”为1的条目id和三个令牌,“看”,“发现”,“跑”,而这些都是在一个单独的符号表,与条目ID相关的给他们,让表可能是这样的:

'see', 1 
'spot', 1 
'run', 1 
'run', 2 
'spot', 3 

回答

6

,你可以在一个查询在MySQL中使用“UNION ALL”实现这一目标。

通过PHP创建UNION ALL每个令牌令牌只是循环:

例如,如果令牌是“X”,“Y”和“Z”您的查询可能是这个样子

SELECT * FROM `entries` 
WHERE token like "%x%" union all 
    SELECT * FROM `entries` 
    WHERE token like "%y%" union all 
     SELECT * FROM `entries` 
     WHERE token like "%z%" ORDER BY score ect... 

order子句应该对整个结果集进行操作,这就是你所需要的。

就性能而言,它不会那么快(我猜测),但是对于数据库而言,速度方面的主要开销通常是将查询从PHP发送到数据库引擎并接收结果。有了这个技巧,这只会发生一次,而不是每个令牌一次,所以性能会提高,我只是不知道它是否足够。

+0

@rmbarnes - 这一定是其中那些UNION OPS我在DB基础年看到后面突然意义;我会明确地给这个性能运行,看看它是如何比较整体速度 – warren 2009-11-05 06:49:28

1

如果您正在使用UNION,你可能还需要包括以下几个部分来查询所有模式:

SELECT COUNT(*) AS C 
... 
GROUP BY ID 
ORDER BY c DESC 

虽然这是一个非常简单的例子,它让你比赛的频率每个结果,这可能是一个伪排名开始。

0

如果您使用专为搜索任务而非数据库设计的数据结构,您可能会获得更好的性能。例如,您可以尝试查看构建inverted index。不过,你可能也想看看Lucene这样的东西,它可以为你做大部分的工作。

3

我知道这并非严格意义上的问题的答案但如果您的表格是数千而不是数百万行,那么FULLTEXT解决方案可能是最好的方法。

在MySQL中,当您在索引列上使用MATCH时,您提供的每个关键字都将被赋予一个相关性分数(大致按照每个关键字被提及的次数计算),这将比您的方法更准确,当然更有效为多个关键字。

在这里看到: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html