我想编写一个查询来搜索包含数百万条记录的表,这些记录的值完全匹配搜索字符串或其子字符串仅从头开始。绩效至关重要。
这就像是一个反面:
SELECT * FROM table_name WHERE column_name LIKE '$input%' LIMIT 1
作为一个例子,我想在下表中搜索foobar。如果foobar不存在,则搜索fooba直到最后一个字符f并返回具有总匹配的行。
+------------------+
| column_name |
+------------------+
| foobar |
+------------------+
| fooba |
+------------------+
| foob |
+------------------+
| foo |
+------------------+
| fo |
+------------------+
| foobarrrrr |
+------------------+
| foooooooooooo |
+------------------+
| barfoo |
+------------------+
您可以使用列值动态构造LIKE
模式。
SELECT column_name
FROM table_name
WHERE 'foobar' LIKE CONCAT(column_name, '%')
ORDER BY LENGTH(column_name) DESC
LIMIT 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
指数进行比较。