Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在SQL中搜索最有效的方法?_Mysql_Sql - Fatal编程技术网

Mysql 在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秒 是否有更好的方法编写查询,是

我的数据库有75000多行,每天添加500多个条目

每行都有标题和说明

我创建了一个RSS提要,为您提供特定搜索词的最新条目(例如,将输出搜索词“Pizza”的RSS)

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

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对数字的搜索快