在SQL中搜索最有效的方法?

[英]Most efficient way to search in SQL?


I have a database with 75,000+ rows with 500+ entries added per day.

我有一个包含75,000多行的数据库,每天添加500多个条目。

Each row has a title and description.

每行都有标题和说明。

I created an RSS feed which gives you the latest entries for a specific search term (ex. http://site.com/rss.rss?q=Pizza would output an RSS for the search term "Pizza").

我创建了一个RSS源,它为您提供特定搜索词的最新条目(例如http://site.com/rss.rss?q=Pizza将输出搜索词“Pizza”的RSS)。

I was wondering what would be the best way to write the SQL query for this. Right now I have:

我想知道为此编写SQL查询的最佳方法是什么。现在我有:

SELECT * 
FROM 'table' 
WHERE (('title' LIKE %searcherm%) OR ('description' LIKE %searcherm%))
LIMIT 20;

But the problem is it takes between 2 to 10 seconds to execute the query.

但问题是执行查询需要2到10秒。

Is there a better way to write the query, do I have to cache the results (and how would I do that?) or would changing something in the database structure speed up the query (indexes?)

有没有更好的方法来编写查询,我是否必须缓存结果(以及我该怎么做?)或者是否会更改数据库结构中的某些内容以加快查询(索引?)

7 个解决方案

#1


8  

A relatively simple solution for this would be incorporating a FULLTEXT index on these two fields and subsequently searching by using this index.

一个相对简单的解决方案是在这两个字段中加入FULLTEXT索引,然后使用该索引进行搜索。

ALTER TABLE table ADD FULLTEXT(title, description);

Then would you need to perform a search, you'd do the following:

然后你需要进行搜索,你会做以下事情:

SELECT id FROM table
WHERE MATCH (title, description) AGAINST ('keyterm');

Fulltext indexed search is the automatic solution included in most SQL databases. It's much speedier comparing to doing LIKES. This is also optimized for your specific case because you are only interested in natural language search terms.

全文索引搜索是大多数SQL数据库中包含的自动解决方案。与做LIKES相比,它要快得多。这也针对您的具体情况进行了优化,因为您只对自然语言搜索术语感兴趣。

As well, fulltext index has some limiting algorithm for detecting relevancy. You can read more about it here

同样,全文索引具有一些用于检测相关性的限制算法。你可以在这里读更多关于它的内容

EDIT

In the alter statement, I missed the fulltext index name, it should be:

在alter语句中,我错过了全文索引名称,它应该是:

ALTER TABLE table ADD FULLTEXT ft_index_name(title, description);

#2


4  

Try:

SELECT * FROM table
WHERE MATCH (title,description) AGAINST (searchterm);

Make sure you add a full text index on title, description together.

确保在标题,描述上一起添加全文索引。

Dont try to reinvent the wheel. MATCH and AGAINST are provided by mysql to do exactly that and to make your life easy. However, note full text search works on MyISAM tables. You can workaround for InnoDb too. You can simply add FT index by altering table like:

不要试图重新发明轮子。 MATCH提供了MATCH和AGAINST来做到这一点,让你的生活更轻松。但是,请注意全文搜索适用于MyISAM表。您也可以为InnoDb解决问题。你可以通过改变表来简单地添加FT索引:

ALTER TABLE table ADD FULLTEXT(title,description);

#3


2  

If you're using a query with LIKE '%term%' the indexes can't be used. They can be used only if you use a query like 'term%'. Think about an address book with tabs, you can find really fast contacts starting with letter L, but to find contacts with a on somewhere in the word, you've to scan the whole addressbook.

如果您使用LIKE'%term%'的查询,则无法使用索引。只有在使用'term%'之类的查询时才能使用它们。想想带有标签的地址簿,你可以找到以字母L开头的真正快速的联系人,但是为了找到单词中某处的联系人,你要扫描整个地址簿。

The better alternative could be to use full text indexes:

更好的选择可能是使用全文索引:

CREATE FULLTEXT INDEX title_desc
ON table (title, description)

And then in the query:

然后在查询中:

SELECT title, description FROM table
WHERE MATCH (title, description) AGAINST ('+Pizza')

#4


0  

I would go with JohnB's or gtr32x's answer (Full Text Indexing). To complement their answer, there's a manual way to create a simple full text index that's simple and it's super fast...

我会选择JohnB's或gtr32x的答案(全文索引)。为了补充他们的答案,有一种手动方式来创建一个简单且超快的简单全文索引......

Split title and description into keywords, and place them in a Keywords table, which has a foreign key to the original RSS article. Make sure the keyword column in Keywords is indexed. The you can do something like:

将标题和描述拆分为关键字,并将它们放在关键字表中,该表具有原始RSS文章的外键。确保关键字中的关键字列已编入索引。你可以这样做:

SELECT DISTINCT ra.* 
FROM RssArticle ra
INNER JOIN Keywords k ON k.ArticleID = ra.ArticleID
   WHERE k IN ( 'SearchTerm1', 'SearchTerm2', 'SearchTerm3')
LIMIT 20;

And it's fast!

它很快!

#5


0  

Try either of the following four queries:

请尝试以下四种查询之一:

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+.*';

the point is to use concat before searching

关键是在搜索之前使用concat

#6


-2  

A few pointers: Drop the * in your select statement and pull only the searched criteria, and make sure to add indexes to the columns that are getting searched.

一些指示:在select语句中删除*并仅提取搜索的条件,并确保将索引添加到要搜索的列中。

SELECT `title`,`description` 
FROM `table` 
WHERE `title` LIKE '%$searchterm%' OR `description` LIKE '%$searchterm%' LIMIT 25;

#7


-2  

  1. Did you create an index for title and for description?
  2. 您是否为标题和描述创建了索引?

  3. You should consider Sphinx for Full Text Search capabilities.
  4. 您应该考虑使用Sphinx进行全文搜索功能。


Thanks for the comment Tyler.

感谢Tyler的评论。

I restate my answer:

我重申一下我的回答:

1) Create an index on title and description columns, but your query would be limited to the example below, and that's not ideal for finding all relevant rows:

1)在标题和描述列上创建索引,但您的查询将仅限于以下示例,并且这不是查找所有相关行的理想选择:

SELECT * 
FROM 'table' 
WHERE title LIKE 'searcherm%' OR description LIKE 'searcherm%'
LIMIT 20;

2) As others have mentioned, use MySQL Full-Text Search, but you are limited to MyISAM table engine, as it isn't available for InnoDB. However, you can mix engines in MySQL, so you can make this table MyISAM, even if all your other tables are InnoDB.

2)正如其他人所提到的,使用MySQL全文搜索,但是你只能使用MyISAM表引擎,因为它不适用于InnoDB。但是,您可以在MySQL中混合引擎,因此即使所有其他表都是InnoDB,您也可以将此表设为MyISAM。

3) Use an external Full-Text Search engine, such as Sphinx. This will give you more relevant search results (MySQL Full-Text Search leaves much to be desired), it will perform better, and it abstracts the burden of Full-Text Searching away from your database.

3)使用外部全文搜索引擎,例如Sphinx。这将为您提供更相关的搜索结果(MySQL全文搜索还有很多不足之处),它会表现得更好,并且它将全文搜索的负担从数据库中抽象出来。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2012/03/06/8a8c7bec28a77093b253612196b27b2f.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号