在FULLTEXT索引上匹配没有返回任何行

时间:2016-05-10 08:23:33

标签: mysql

我有一个在线日记,其中两个主要的MyISAM表是:

**tbl_log_days**

Name                Type
ID                  int(11)
post_date           date
post_content        longtext
post_entry_date     datetime
post_cat_id         int(11)
post_update_date    datetime

**tbl_log_cats**

Name                Type
fld_id              int(11)
fld_cat             varchar(255)

第一个商店日详情,第二个商店类别。

根据这篇文章的建议,我一直在尝试使用MATCH AGAINST全文搜索:

使用全文索引进行高级文本搜索 http://www.hackingwithphp.com/9/3/18/advanced-text-searching-using-full-text-indexes

“tbl_log_days”表中有一个索引:

Keyname: post_content
Type: FULLTEXT
Unique: No
Packed: No
Column: post_content
Cardinality: 2

当我运行此搜索时:

    SELECT d.ID
         , d.post_date 
         , d.post_content
         , d.post_cat_id
         , d.post_label
         , c.fld_cat
      FROM tbl_log_days d
         , tbl_log_cats c
     WHERE d.post_cat_id = c.fld_id
       AND post_content LIKE '%saying%'
       AND c.fld_id = 101
       AND YEAR(post_date) = 2003
  ORDER BY post_date;

它返回5行,“post_content”值包含完整的单词“say”。

当我运行此SQL时:

    SELECT d.ID
         , d.post_date 
         , d.post_content
         , d.post_cat_id
         , d.post_label
         , c.fld_cat
      FROM tbl_log_days d
         , tbl_log_cats c
     WHERE d.post_cat_id = c.fld_id
       AND (MATCH(post_content) AGAINST ('saying') AND c.fld_id = 101 AND YEAR(post_date) = 2003)
  ORDER BY post_date;

它不返回任何行。

这也不会返回任何内容:

    SELECT d.ID
         , d.post_date 
         , d.post_content
         , d.post_cat_id
         , d.post_label
         , c.fld_cat
      FROM tbl_log_days d
         , tbl_log_cats c
     WHERE d.post_cat_id = c.fld_id
       AND MATCH(post_content) AGAINST ('saying')
       AND c.fld_id = 101
       AND YEAR(post_date) = 2003
  ORDER BY post_date;

这样做 - 例如删除连接到类别表的可能问题:

    SELECT d.ID
         , d.post_date 
         , d.post_content
         , d.post_cat_id
         , d.post_label
      FROM tbl_log_days d
     WHERE MATCH(post_content) AGAINST ('saying');

索引是否有问题 - 我想如果一个LIKE'%说'%'返回5行,那么MATCH AGAINST也应该这样做?

1 个答案:

答案 0 :(得分:0)

让我们直截了当地说:

post_content LIKE '%saying%'

不同
MATCH(post_content) AGAINST ('saying')
  1. like运算符执行简单的模式匹配。如果你在帖子内容中有文字'谚语',就会返回它。在默认的自然语言模式下进行全文搜索不会返回此记录,因为说的与单词不同。

  2. like运算符将返回与模式匹配的所有记录,无论总数中有多少记录与总体匹配。在默认自然语言模式下的全文搜索会将超过50%的总记录中存在的任何值视为噪音,并且不会返回任何仅与该条件匹配的记录。

  3. 应用于全文搜索的最小字长属性。如果你的最小字长超过'说'的长度,那么mysql将忽略这个标准。 like运营商并不关心此类事情。

  4. Mysql在fulltext search上有一个非常详细的文档,其中描述了上述所有内容以及更多内容。