带有FT INDEX的MyIsam表上的COUNT(*)

时间:2016-01-14 10:08:32

标签: mysql myisam full-text-indexing

在mySQL 5.5中的myISAM表上使用FULL TEXT INDEX时我有些疑惑。

我有这样的表:

    CREATE TABLE `search_descr` (
      `vid` int(11) NOT NULL,
      `v_name_text` text COLLATE utf8_polish_ci,
      `d_title` text COLLATE utf8_polish_ci,
      `d_title_stemmed` text COLLATE utf8_polish_ci,
      `r_name` text COLLATE utf8_polish_ci,
      `r_name_stemmed` text COLLATE utf8_polish_ci,
      `c_title` text COLLATE utf8_polish_ci,
      `v_kind` text COLLATE utf8_polish_ci,
      `v_kind_stemmed` text COLLATE utf8_polish_ci,
      `i_title_pl_text` text COLLATE utf8_polish_ci,
      `i_title_latin_text` text COLLATE utf8_polish_ci,
      `i_title_text` text COLLATE utf8_polish_ci,
      `descr` text COLLATE utf8_polish_ci,
      PRIMARY KEY (`vid`),
      FULLTEXT KEY `descr_FT_indx` (`descr`),
      FULLTEXT KEY `all_FT_indx` (`v_name_text`,`d_title`,`d_title_stemmed`,`i_title_pl_text`,
         `i_title_latin_text`,`i_title_text`,`r_name`,`r_name_stemmed`,`c_title`,
         `v_kind`,`v_kind_stemmed`,`descr`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

我在那里插入我的数据,所有列都是合理的短,除了descr - > AVG长度(descr)约为8000.我插入大约15000行。

现在我想计算满足条件的行(条件是任何列中任何给定单词都匹配)。所以我提出了一个问题:

      SELECT 
          COUNT(*)
      FROM
          (SELECT 
              vid
          FROM
              search_descr
          WHERE
              MATCH (v_name_text , d_title , d_title_stemmed , i_title_pl_text ,
    i_title_latin_text , i_title_text , r_name , r_name_stemmed , c_title ,
    v_kind , v_kind_stemmed , descr)
    AGAINST ('ok* oko* około*' IN BOOLEAN MODE)) a

需要4才能给我一个答案(11674行)。

另一个查询要快得多:

          SELECT 
              COUNT(*)
          FROM
              (SELECT 
                  vid
              FROM
                  search_descr
              WHERE
                  MATCH (v_name_text , d_title , d_title_stemmed , i_title_pl_text ,
     i_title_latin_text , i_title_text , r_name , r_name_stemmed , c_title ,
     v_kind , v_kind_stemmed , descr)
     AGAINST ('oko*' IN BOOLEAN MODE) UNION SELECT 
                  vid
              FROM
                  search_descr
              WHERE
                  MATCH (v_name_text , d_title , d_title_stemmed , i_title_pl_text ,
      i_title_latin_text , i_title_text , r_name , r_name_stemmed , c_title ,
      v_kind , v_kind_stemmed , descr)
      AGAINST ('około*' IN BOOLEAN MODE) UNION SELECT 
                  vid
              FROM
                  search_descr
              WHERE
                  MATCH (v_name_text , d_title , d_title_stemmed , i_title_pl_text ,
      i_title_latin_text , i_title_text , r_name , r_name_stemmed , c_title ,
      v_kind , v_kind_stemmed , descr)
      AGAINST ('ok*' IN BOOLEAN MODE)) a
                  INNER JOIN
              search_descr v USING (vid)

我认为这需要不到0,180秒这是合理的。

问题是: 我在第一个查询中做错了什么?为什么我不能使用MATCH AGAINST及其所有好处(例如“反对(+(oko *około*)+(dlaczego)在BOOLEAN模式中)”等等?

注意:我知道搜索oko *是多余的,因为结果将完全包含在ok *的结果中,但它不会改变问题。我的程序也可以生成完全不同的单词

注意2:COUNT仅用于显示案例。一般来说,我需要对收到的数据做一些事情,按照匹配的列的相关性,通过其他条件,添加偏移量和限制来对其进行排序。

0 个答案:

没有答案