Mysql 在SQL中搜索最有效的方法?
我的数据库有75000多行,每天添加500多个条目 每行都有标题和说明 我创建了一个RSS提要,为您提供特定搜索词的最新条目(例如,将输出搜索词“Pizza”的RSS) 我想知道为这个编写SQL查询的最佳方法是什么。现在我有:Mysql 在SQL中搜索最有效的方法?,mysql,sql,Mysql,Sql,我的数据库有75000多行,每天添加500多个条目 每行都有标题和说明 我创建了一个RSS提要,为您提供特定搜索词的最新条目(例如,将输出搜索词“Pizza”的RSS) 我想知道为这个编写SQL查询的最佳方法是什么。现在我有: SELECT * FROM 'table' WHERE (('title' LIKE %searcherm%) OR ('description' LIKE %searcherm%)) LIMIT 20; 但问题是执行查询需要2到10秒 是否有更好的方法编写查询,是
SELECT *
FROM 'table'
WHERE (('title' LIKE %searcherm%) OR ('description' LIKE %searcherm%))
LIMIT 20;
但问题是执行查询需要2到10秒
是否有更好的方法编写查询,是否必须缓存结果(我将如何缓存结果?),或者更改数据库结构中的某些内容是否会加快查询速度(索引?一些指针:在select语句中删除*并仅提取搜索的条件,并确保向要搜索的列添加索引
SELECT `title`,`description`
FROM `table`
WHERE `title` LIKE '%$searchterm%' OR `description` LIKE '%$searchterm%' LIMIT 25;
标题
和说明
创建了索引谢谢泰勒的评论 我重申我的回答: 1) 在
title
和description
列上创建索引,但您的查询仅限于以下示例,这不适合查找所有相关行:
SELECT *
FROM 'table'
WHERE title LIKE 'searcherm%' OR description LIKE 'searcherm%'
LIMIT 20;
2) 正如其他人提到的,使用MyISAM表引擎,但您仅限于MyISAM表引擎,因为它不适用于InnoDB。但是,您可以在MySQL中混合使用引擎,这样您就可以使这个表成为MyISAM,即使您的所有其他表都是InnoDB
3) 使用外部全文搜索引擎,例如。这将为您提供更多相关的搜索结果(MySQL全文搜索还有很多需要改进的地方),它的性能会更好,并且它将全文搜索的负担从您的数据库中剥离出来。试试:
SELECT * FROM table
WHERE MATCH (title,description) AGAINST (searchterm);
请确保在标题、说明中同时添加全文索引
不要试图重新发明轮子<代码>匹配和对抗
正是为了做到这一点,让你的生活变得轻松。但是,请注意,全文搜索在MyISAM表上起作用。你也支持InnoDb。您只需通过如下更改表来添加FT索引:
ALTER TABLE table ADD FULLTEXT(title,description);
如果使用的查询具有“%term%”之类的
,则无法使用索引。只有在使用类似于'term%'
的查询时,才能使用它们。想想有标签的通讯录,你可以找到以字母L
开头的快速联系人,但是要找到单词中某个地方有的联系人,你必须扫描整个通讯录
更好的选择是使用全文索引:
CREATE FULLTEXT INDEX title_desc
ON table (title, description)
然后在查询中:
SELECT title, description FROM table
WHERE MATCH (title, description) AGAINST ('+Pizza')
一个相对简单的解决方案是在这两个字段上合并全文索引,然后使用该索引进行搜索
ALTER TABLE table ADD FULLTEXT(title, description);
如果需要执行搜索,请执行以下操作:
SELECT id FROM table
WHERE MATCH (title, description) AGAINST ('keyterm');
全文索引搜索是大多数SQL数据库中包含的自动解决方案。这比做喜欢的事要快得多。这也针对您的具体情况进行了优化,因为您只对自然语言搜索词感兴趣
此外,全文索引还有一些检测相关性的限制性算法。你可以阅读更多关于它的内容
编辑
在alter语句中,我遗漏了全文索引名,它应该是:
ALTER TABLE table ADD FULLTEXT ft_index_name(title, description);
我会选择JohnB或gtr32x的答案(全文索引)。为了补充他们的答案,有一个手动方法来创建一个简单的全文索引,它很简单,而且非常快
将标题和描述拆分为关键字,并将它们放在关键字
表中,该表具有原始RSS文章的外键。确保已为关键字
中的关键字列编制索引。您可以执行以下操作:
SELECT DISTINCT ra.*
FROM RssArticle ra
INNER JOIN Keywords k ON k.ArticleID = ra.ArticleID
WHERE k IN ( 'SearchTerm1', 'SearchTerm2', 'SearchTerm3')
LIMIT 20;
而且很快 尝试以下四个查询之一:
select * from myTable where concat_ws(' ',title,description) like '%pizza%';
select * from myTable where concat_ws(' ',title,description) regexp '.*pizza+.*';
select title,description from myTable where concat_ws(' ',title,description) like '%pizza%';
select title,description from myTable where concat_ws(' ',title,description) regexp '.*pizza+.*';
关键是在搜索之前使用concat可能会更快地执行单个线程/将处理分为两个简单的查询:select from table where title limit 20
然后select from table where description limit 20
诸如此类的事情,然后使用服务器端的techIndex进行连接/列表concat在这里没有帮助。例如“%foo%”从不使用索引。这是他的真正问题。“在select语句中删除*并只提取搜索的条件”-那么你怎么知道他想要检索什么?我不知道,但根据他的WHERE子句,我可以确定他至少需要标题和描述。不管怎样,最好指定表而不是通配符,他询问如何加快查询速度,消除通配符是第一步。有一个限制是20。。我怀疑它是否会产生任何可测量的差异。由于前导“%”,标准化索引在这里对您没有帮助。它们只会占用空间,不会被使用。(另外,您的搜索词没有正确转义。)您可以使用全文索引和MATCH
运算符,但只能在MyISAM
表上使用。这是唯一有效的答案。请注意,您需要向这些列添加全文索引,并且必须使用MyISAM表。@FrancisAvila更新了我的答案。请注意,这只适用于MyISAM表,而不适用于InnoDB。非常感谢!!!我测试了这个,它使我的搜索速度平均提高了14倍!!!!!!!全文也适用于数字吗?@FrancisAvila自MySQL 5.6以来,InnoDB支持全文搜索。这大约快了2倍,但不如MATCH对数字的搜索快