处理模式类似的项目:
id , key, value
key
和value
列是varchar,表格是InnoDB
。
用户可以根据键值对进行搜索......什么是在MySQL中查询的最佳方式?我能想到的选择是:
为每个key => value
形成一个查询并执行inner join
以使id
与所有标准相匹配。
或者在后台,使用MyISAM
上的id, info
表Full Text index
填充info
,使用like '%key:value%key2:value2%'
填充单个查询。如果网站很受欢迎并且表格有十万行,我可以轻松将代码移植到Lucene,但现在是MySQL。
答案 0 :(得分:2)
您所谈论的模式称为关系划分。
如果你有正确的索引,选项#1(自联接)是一个更快的解决方案。
我在演示文稿中将两种解决方案的性能与关系划分进行了比较 SQL Query Patterns, Optimized。自连接解决方案在0.005秒内工作,甚至对数百万行的表也是如此。
带有全文的选项#2无论如何都不正确,因为您不会将LIKE
用于全文搜索。你使用MATCH(info) AGAINST('...' IN BOOLEAN MODE)
。我不确定你是否可以使用key:value
格式的模式。 MySQL FTS更喜欢匹配单词。
答案 1 :(得分:0)
@Bill Karwin
如果你打算在1个条件下执行此操作,那么使用这种类似EAV的模式会非常快,但是如果你为很多人(特别是使用混合的AND和OR)执行此操作,它可能会崩溃。您可以期待的最好的是某种超快速索引合并,这是难以捉摸的。如果你做任何花哨的事情,你将在大多数DBMS中获得一个临时表。我想我记得你读过你不是EAV的粉丝,也许我误解了你。
我记得,DBMS也可以自由地进行多次扫描,然后用一次性位图索引来处理它。但全文索引使文档列表保持排序,并使用FTS规划器在所有条件下进行低成本合并,该策略规划器使用稀有关键字进行策略性启动。这就是他们整天执行“word1& word2”所做的一切。他们针对这类事情进行了优化。
所以如果你有很多简单的事实,我认为FTS指数是一种不错的方法。我错过了什么吗?您只需要将事实更改为可索引的内容(如COLORID_3),然后搜索“COLORID_3& SOMETHINGELSEID_5。”
如果查询不涉及合并或排序,我怀疑它几乎就像清洗一样。这里没什么,但我们BTREEs ......