2012-01-03 47 views
2

我有一个查询我需要运行,目前运行速度非常慢。我正在使用的表格有近100万条记录。MYSQL查询,优化LIKE,而不是在

我需要做什么是对与LIKE名称项搜索:例"SELECT name, other, stuff FROM my_table WHERE name LIKE '%some_name%'"

此外,它必须能够排除某些方面与从搜索结果中通配符所以它变成是这样的:

SELECT name, other, stuff 
FROM my_table 
WHERE name LIKE '%some_name%' 
AND name NOT IN (SELECT name FROM my_table WHERE name LIKE '%term1%' AND name LIKE '%term2%' AND name LIKE '%term3%') 

最重要的是,我有两个INNER JOIN,我必须在PHP中执行它。我在表中列出了相关列的索引。它在服务器上的速度非常快,几乎可以对其他任何查询进行处理。

问题是,有没有一种不同的方法可以用来做这种类型的查询,这很快?

最新通报

这是添加在FULLTEXT索引的表化学,并试图匹配功能,而不是经过我的实际查询。注:我无法控制表/列名称。我知道他们看起来不错。

CREATE FULLTEXT INDEX name_index ON chems (name) 

SELECT f.name fname, f.state, f.city, f.id fid, 
cl.alt_facilid_ida, cl.alt_facili_idb, 
c.ave, c.name, c.id chem_id, 
cc.first_name, cc.last_name, cc.id cid, cc.phone_work 
FROM facilities f 
INNER JOIN facilitlt_chemicals_c cl ON (f.id = cl.alt_facilid485ilities_ida) 
INNER JOIN chems c ON (cl.alt_facili3998emicals_idb = c.id) 
LEFT OUTER JOIN facilities_contacts_c con ON (f.id = con.alt_facili_ida) 
LEFT OUTER JOIN contacts cc ON (con.alt_facili_idb = cc.id) 
WHERE match(c.name) against ('+lead -gas' IN BOOLEAN MODE) 

这只是一个简单查询的例子。实际条件可能很多。

+1

你对MY_TABLE主键或唯一的ID结合MySQL和狮身人面像查询?如果所以它可能会更快地做'...和id不在(选择id从...' – cmbuckley 2012-01-03 19:01:07

+1

而不是一个子选择我会简单地做: 其中名称LIKE'%some_name%' AND name NOT LIKE'%term1%' AND name not LIKE'%term2%' AND name not LIKE'%term3%' 这样会更快 – 2012-01-03 19:18:36

+0

另外,如果您使用子选择,您应该分开您的条件OR,而不是AND,除非它们全部都需要 – 2012-01-03 19:19:41

回答

5

你想在你正在搜索的列上实现MySQL的全文功能。详细了解它here

而且,你可能想要做的布尔搜索:

select 
    t1.name, 
    t1.stuff 
from 
    my_table t1 
where 
    match(t1.name) against ('+some_name -term1 -term2 -term3' in boolean mode) 
+1

我也可以建议'boolean mode' serching(http://dev.mysql.com/doc/refman/5.0/en/fulltext- boolean.html),它将添加符号,如+和 - 来要求或排除单词。还有什么是加入点/'不在'。这甚至可以通过匹配('+ some_name -term1 -term2')''match(t1.name)' – 2012-01-03 19:06:46

+0

@JonathanKuhn - 伟大的建议来删除join /'not in'。我已经使用MySQL全文搜索已经有好几年了,所以谢谢你填补空白:) – Eric 2012-01-03 19:07:38

+1

修复'('+ some_name -term1 -term2'BOOLEAN模式)''。 – 2012-01-03 19:09:31

1

我会建议使用像Lucene的或狮身人面像外部全文引擎。特别是如果您打算针对相对较大的数据集启动搜索查询。

在狮身人面像的情况下,你可以使用一个叫做SphinxQL SELECT语法类似的要求,这将做的正是:在http://sphinxsearch.com/docs/current.html#extended-syntax(你的情况不是运营商)所描述的

SELECT * FROM <sphinx_index_name> WHERE MATCH('some_name -term1 -term2 -term3'); 

。另外,您可以启用形态支持,这可能也有帮助。

您可以http://sphinxsearch.com/docs/current.html#sphinxse