我想编写一个查询来搜索包含数百万条记录的表,以查找完全并且最从开始就最匹配搜索字符串或其子字符串的值。性能是最重要的。
这就像相反:
SELECT * FROM table_name WHERE column_name LIKE '$input%' LIMIT 1
举例来说,我想在下表中搜索<strong> foobar 。如果 foobar 不存在,请搜索 fooba ,直到最后一个字符 f 并返回总匹配的行。
+------------------+
| column_name |
+------------------+
| foobar |
+------------------+
| fooba |
+------------------+
| foob |
+------------------+
| foo |
+------------------+
| fo |
+------------------+
| foobarrrrr |
+------------------+
| foooooooooooo |
+------------------+
| barfoo |
+------------------+
答案 0 :(得分:1)
我认为没有一种真正有效的方法,但是以下方法可能会满足您的要求。
首先,在t(column_name)
上创建索引。
然后,将查询构造为:
select t.*
from ((select t.* from table_name where column_name = $input) union all
(select t.* from table_name where column_name = left($input, 1)) union all
(select t.* from table_name where column_name = left($input, 2)) union all
(select t.* from table_name where column_name = left($input, 3)) union all
(select t.* from table_name where column_name = left($input, 4)) union all
. . .
) t
order by length(t.column_name) desc
limit 1;
注意:
$input
的不同长度的前缀。您可以使用PHP进行操作,并在第一个比赛时停止。column_name
上的索引进行比较。答案 1 :(得分:1)
您可以使用列值动态构建LIKE
模式。
SELECT column_name
FROM table_name
WHERE 'foobar' LIKE CONCAT(column_name, '%')
ORDER BY LENGTH(column_name) DESC
LIMIT 1
请注意,如果表很大,这会很慢,因为我认为它不能利用索引。如果存在问题,则动态构建查询会更好。