Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.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 Innodb全文搜索失败,MyIsam返回结果_Mysql_Full Text Search_Innodb_Myisam_Mysql 5.6 - Fatal编程技术网

Mysql Innodb全文搜索失败,MyIsam返回结果

Mysql Innodb全文搜索失败,MyIsam返回结果,mysql,full-text-search,innodb,myisam,mysql-5.6,Mysql,Full Text Search,Innodb,Myisam,Mysql 5.6,我已经将一个表从myisam升级到innodb,但没有相同的性能。当应该存在某种关系时,innodb返回一个0分数。myisam表返回同一术语的匹配项(我保留了旧表的一个副本,以便仍然可以运行相同的查询) 返回: +-------+ | score | +-------+ | 1 | +-------+ 但是: 返回: +-------+ | score | +-------+ | 0 | +-------+ 我认为ex可能没有被索引,因为innodb\u ft\u min\

我已经将一个表从
myisam
升级到
innodb
,但没有相同的性能。当应该存在某种关系时,
innodb
返回一个
0
分数。
myisam
表返回同一术语的匹配项(我保留了旧表的一个副本,以便仍然可以运行相同的查询)

返回:

+-------+
| score |
+-------+
|     1 |
+-------+
但是:

返回:

+-------+
| score |
+-------+
|     0 |
+-------+
我认为
ex
可能没有被索引,因为
innodb\u ft\u min\u token\u size
被设置为
3
。我将其降低到
1
,并优化了表格,但没有任何影响。列内容有99个字符长,因此我假设整个列没有被索引,因为
innodb\u ft\u max\u token\u size
。我也将其增加到
150
,并再次运行优化,但再次得到相同的结果

这些表之间的唯一区别是引擎和字符集。此表使用的是
utf8
myisam
表使用的是
latin1

有没有人看到过这些行为,或者对如何解决它有什么建议

更新: 我将
ft\u stopword\u file=”“
添加到我的
my.cnf
中,并再次运行
优化表。这次我得到了

优化|注意|表格不支持优化,改为重新创建+分析

此更改后,查询工作正常
Ex
不是一个停止词,但不知道为什么它会起作用

但失败的新查询是:

SELECT MATCH (Columns) AGAINST ('+Term +Ex +in' IN BOOLEAN MODE) as score FROM Table where id = 1;

+-------+
| score |
+-------+
|     0 |
+-------+
中的
导致此操作失败,但这是我表格中的下一个单词

SELECT MATCH (Columns) AGAINST ('+Term +Ex' IN BOOLEAN MODE) as score FROM Table where id = 1;

+--------------------+
| score              |
+--------------------+
| 219.30206298828125 |
+--------------------+
我还尝试了
创建表my_stopwords(value VARCHAR(30))ENGINE=INNODB
,然后使用
innodb\u ft\u服务器\u stopword\u table='db/my\u stopwords'更新
my.cnf
。我重新启动并运行:

show variables like 'innodb_ft_server_stopword_table';
这带来了:

+---------------------------------+---------------------------+
| Variable_name                   | Value                     |
+---------------------------------+---------------------------+
| innodb_ft_server_stopword_table | 'db/my_stopwords'; |
+---------------------------------+---------------------------+
所以我认为
中的
不会导致现在的查询失败,但它会继续。我还再次尝试了
optimizetable TABLE
,甚至
alterttable TABLE DROP INDEX…
alterttable TABLE ADD FULLTEXT KEY…
都没有效果

第二次更新 问题在于停止语

$userinput = preg_replace('/\b(a|about|an|are|as|at|be|by|com|de|en|for|from|how|i|in|is|it|la|of|on|or|that|the|this|to|was|what|when|where|who|will|with|und|the|www)\b/', '', $userinput);
解决了这个问题,但这对我来说并不是一个好的解决方案。我想要一个解决方案,避免停止词打破mysql这一点

停止字表数据:

CREATE TABLE `my_stopwords` (
  `value` varchar(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1


MyISAM的全文和InnoDB的全文有几个不同之处。我认为你被“短”字和/或“停止”字的处理抓住了。MyISAM将显示行,但InnoDB将无法显示行

我在使用FT时(以及切换到InnoDB后)所做的是过滤用户的输入,以避免短词。这需要额外的努力,但能让我达到所需的行数。我的情况略有不同,因为结果查询是这样的。请注意,我添加了
+
以要求输入单词,但不要求输入短于3的单词(我的
ft\u min\u token\u size
为3)。这些搜索用于
构建表格
构建表格

WHERE match(description) AGAINST('+build* a +table*' IN BOOLEAN MODE)
WHERE match(description) AGAINST('+build* +the* +table*' IN BOOLEAN MODE)
(尾随的
*
可能是多余的;我没有对此进行调查。)

另一种方法

由于FT在不短、不间断的单词方面非常有效,因此搜索分为两个阶段,每个阶段都是可选的:要搜索“长单词”,请执行以下操作

要仅搜索单词“a”:

其中d REGEXP'[[::]]
警告:这种情况将是缓慢的


注意:我的示例允许单词在字符串中的任何顺序和位置。也就是说,在我所有的例子中,这个字符串都是匹配的:“她渴望从他那里得到一个词。”

这里是一个循序渐进的过程,应该重现您的问题。(这实际上是你应该如何写你的问题。)环境是一个新安装的虚拟机,带有Debian 9.8和Percona服务器版本5.6.43-84.3

  • 使用全文索引和一些虚拟数据创建InnoDB表:

    create table test.ft_innodb (
        txt text,
        fulltext index (txt)
    ) engine=innodb charset=utf8 collate=utf8_unicode_ci;
    
    insert into test.ft_innodb (txt) values
        ('Some dummy text'),
        ('Text with a long and short stop words in it ex');
    
  • 执行一个测试查询,以验证它是否按照我们的需要工作:

    select txt
        , match(t.txt) against ('+some' in boolean mode) as score0
        , match(t.txt) against ('+with' in boolean mode) as score1
        , match(t.txt) against ('+in'   in boolean mode) as score2
        , match(t.txt) against ('+ex'   in boolean mode) as score3
    from test.ft_innodb t;
    
    结果(四舍五入):

    如您所见,它不适用于停止词(“+with”)或短词(“+ex”)

  • 为自定义停止字创建空InnoDB表:

    create table test.my_stopwords (value varchar(30)) engine=innodb;
    
  • 编辑
    /etc/mysql/my.cnf
    并在
    [mysqld]
    块中添加以下两行:

    [mysqld]
    # other settings
    innodb_ft_server_stopword_table = "test/my_stopwords"
    innodb_ft_min_token_size = 1
    
  • 使用
    service MySQL Restart重新启动MySQL

  • 再次从(2.)运行查询(结果应相同)

  • 使用以下命令重建全文索引:

    它将实际重建整个选项卡,包括所有索引

  • 再次执行来自(2.)的测试查询。现在的结果是:

    txt                                            | score1 | score1 | score2 | score3
    -----------------------------------------------|--------|--------|--------|-------
    Some dummy text                                | 0.0906 | 0      | 0      | 0
    Text with a long and short stop words in it ex | 0      | 0.0906 | 0.0906 | 0.0906
    
  • 你看,这对我来说很好。而且很容易复制。(同样,这是你应该如何写你的问题。)

    由于你的程序相当混乱而不是详细,很难说你会出什么问题。例如:

    CREATE TABLE my_stopwords(value VARCHAR(30)) ENGINE = INNODB;
    
    这不包含您在哪个数据库中定义该表的信息。请注意,我已在所有表前面加上了相应数据库的前缀。现在考虑下面的内容:我改变<代码>我的.CNF并设置<代码> NoNdByftServIsStudiWordDeTab= =“Db/MyOxStaseWord”< /C>。注意-我的服务器上没有这样的表(甚至架构
    db
    也不存在)。重新启动MySQL服务器。并使用检查新设置

    show variables like 'innodb_ft_server_stopword_table';
    
    这将返回:

        Variable_name                   | Value
        --------------------------------|----------------
        innodb_ft_server_stopword_table | db/my_stopwords
    
    优化表test.ft_innodb之后测试查询返回以下内容:

        txt                                            | score0 | score1 | score2 | score3
        -----------------------------------------------|--------|--------|--------|-------
        Some dummy text                                | 0.0906 | 0      | 0      | 0
        Text with a long and short stop words in it ex | 0      | 0      | 0      | 0.0906
    

    看到了吗?它不再适用于stopwords。但它适用于像“+ex”这样不停的短单词。因此,请确保您在innodb\u ft\u server\u stopword\u表中定义的表确实存在。

    搜索中的一种常见技术是使用“已消毒”字符串创建一个额外的列进行搜索。然后将全文索引添加到该列
    create table test.my_stopwords (value varchar(30)) engine=innodb;
    
    [mysqld]
    # other settings
    innodb_ft_server_stopword_table = "test/my_stopwords"
    innodb_ft_min_token_size = 1
    
    optimize table test.ft_innodb;
    
    txt                                            | score1 | score1 | score2 | score3
    -----------------------------------------------|--------|--------|--------|-------
    Some dummy text                                | 0.0906 | 0      | 0      | 0
    Text with a long and short stop words in it ex | 0      | 0.0906 | 0.0906 | 0.0906
    
    CREATE TABLE my_stopwords(value VARCHAR(30)) ENGINE = INNODB;
    
    show variables like 'innodb_ft_server_stopword_table';
    
        Variable_name                   | Value
        --------------------------------|----------------
        innodb_ft_server_stopword_table | db/my_stopwords
    
        txt                                            | score0 | score1 | score2 | score3
        -----------------------------------------------|--------|--------|--------|-------
        Some dummy text                                | 0.0906 | 0      | 0      | 0
        Text with a long and short stop words in it ex | 0      | 0      | 0      | 0.0906