MySQL 命令
显示字符集
全文检索在 MySQL 中就是一个 FULLTEXT 类型索引。FULLTEXT 索引用于 MyISAM 表(mysql 5.6+ 可以用于 innodb),可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、 VARCHAR 或 TEXT 列上创建。对于大的数据库,将数据装载到一个没有 FULLTEXT 索引的表中,然后再使用 ALTER TABLE (或 CREATE INDEX) 创建索引,这将是非常快的。将数据装载到一个已经有 FULLTEXT 索引的表中,将是非常慢的。
1.使用Mysql全文检索fulltext的先决条件
表的类型必须是MyISAM 或者 mysql 5.6+
使用 innodb
建立全文检索的字段类型必须是char
,varchar
,text
2.建立全文检索先期配置
由于Mysql的默认配置是索引的词的长度是4,所以要支持中文单字的话,首先更改这个.*Unix
用户要修改 my.cnf
,一般此文件在 /etc/my.cnf
,如果没有找到,先查找一下find / -name 'my.cnf'
在[mysqld] 位置内加入:
1 | <!-- more --> |
语雀镜像 : [转]MySQL配置文件my.cnf 例子最详细翻译 ,点此 提问
1 | [mysqld] |
数据库属于IO密集型的应用程序,主要职责是数据的管理和存储工作。从内存中读取数据的速度远远大于从磁盘上读取数据,所以优化数据库就是尽可能的将磁盘IO转化为内存IO。接下来介绍的是IO相关参数(缓存参数):
skip-name-resolve
:
如果启用此参数, mysql日志显示[Warning] IP address ‘xxxx’ could not be resolved: Name or service not known,那是因为mysql默认会反向解析DNS,对于访问者Mysql不会判断是hosts还是ip都会进行dns反向解析,频繁地查询数据库和权限检查,这大大增加了数据库的压力,导致数据库连接缓慢,严重的时候甚至死机,出现“连接数据库时出错”等字样。
back_log
:
back_log 指MySQL暂时停止响应新的请求之前,多少个请求可以被存在堆栈中。(如果MySQL的连接达到max_connection后,新来的请求将会被存在堆栈中,以等待某一连接释放资源)
注:back_log超过TCP/IP连接的侦听队列的大小则无效,查看命令:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
wait_timeout
(单位:秒) :
mysql客户端与服务端的连接最长闲置时间,到达后将会被强行关闭。MySQL默认的wait_timeout为8个小时。
interactive_timeout:服务器关闭交互式连接前等待的秒数。
wait_timeout:服务器关闭非交互连接之前等待活动的秒数。(心跳?)
这两个参数必须配合使用。单独设置wait_timeout则无效。
max_connections
:
max_connections是指MySQL的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并发连接数据量。
MySQL服务器允许的最大连接数量: 16384
max_user_connection
:
max_user_connections:是指每个数据库用户的最大连接。
默认值0:表示不受限制
max_used_connections:指MySQL服务启动到此刻,同一时刻并行连接的最大值。查看方式:
show status like “max_used_connections”
thread_concurrency
:
thread_concurrency 对MySQL的性能影响很大,错误的设置thread_concurrency的值会导致MySQL不能充分利用CPU。
thread_concurrency应设为CPU核数的2倍。比如,2个双核的CPU,thread_concurrency的值应为2_2_2=8
key_buffer_size
:
key_buffer_size是用于索引块的缓冲区大小,调整该值的大小能够更好的处理索引(对所有读和多重写),严格来说它决定了数据库索引的处理速度,尤其是读索引块的速度
检查状态值:Key_read_requests和Key_read的比值,检查该值设置是否合理, Key_read:Key_read_requests应尽可能小
MySQL > show status like “Key_read%”;
+——————-+————-+
| Variable_name | Value |
+——————-+————-+
| Key_read_requests | 35072256038 |
| Key_reads | 593121872 |
+——————-+————-+
一般未命中率在0.1以下比较好
innodb_buffer_pool_size
:
缓冲池是数据和索引缓存的地方。
检查状态值:Innodb_buffer_pool_read_requests 和Innodb_buffer_pool_reads 可计算出该值设置的是否合理, (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 计算缓存命中率,缓存命中率越高越好
mysql> show status like “innodb_buffer_pool_r%”;
+—————————————+————-+
| Variable_name | Value |
+—————————————+————-+
| Innodb_buffer_pool_read_requests | 10585231877 |
| Innodb_buffer_pool_reads | 2083477 |
+—————————————+————-+
2 rows in set (0.01 sec)
innodb_additional_mem_pool_size
:
设置了InnoDB存储引擎用来存放数据字典信息以及一些内部数据的内存空间大小
查看MySQL的 error 日志,如果发现很多warning警告就需要调大该值
innodb_log_buffer_size
:
innodb_log_buffer_size:设置InnoDB将日志写入日志磁盘文件前的缓冲大小。大的日志缓冲允许事务运行时不需要将日志保存到磁盘直到事务被提交(commit)。大的日志缓冲可以减少磁盘I/O,默认值为8M,一般来说不建议超过32M
注:innodb_flush_log_trx_commit参数对innodb log的写入性能有非常关键的影响,默认值为1。
1 | 0:log buffer中的数据将以每秒一次的频率写入到log file中,且同时会进行文件系统到磁盘的同步操作,但是每个事务的commit并不会触发任何log buffer 到log file的刷新或者文件系统到磁盘的刷新操作; |
query_cache_size
query_cache_size主要用来缓存mysql的结果集,所以仅针对于select语句。致命缺陷是当某个表的数据有任何变化,都会导致所有引用该表的select语句在query cache中的缓存数据失效。当数据变化非常多的情况下,不建议使用。
query_cache_size和query_cache_type需要配合使用,query_cache_type设置在何种场景下使用,0(off)表示完全不使用,1(on)除显示要求不使用外均使用,2(demond)只有显示要求才使用
MySQL还为每个连接设置连接缓存,每个连接包含线程堆栈,网络缓存等,默认的大小为256K 。事务开始之后,则需要更多的空间。运行较小的查询可能仅给指定的线程增加少量的内存消耗,然而如果对数据表做复杂的操作例如全表扫描、排序或者临时表,则需要分配read_buffer_size、sort_buffer_size、read_rnd_buffer_size、tmp_table_size 大小的内存空间,不过它们是在需要的时候分配,并且在操作完成之后就释放了。tmp_table_size 可以达到MySQL所能分配给这个操作的最大内存空间。
read__buffer_size
:
read_buffer_size是MySQL读入缓存区大小。对表进行顺序扫描的请求将分配一个读入缓冲区。
sort_buffer_size
sort_buffer_size是MySQL执行排序使用的缓冲大小
read_rnd_buffer_size
read_rnd_buffer_size是MySQL随机读缓冲区大小。
tmp_table_size
tmp_table_size是MySQL的heap(堆)表缓冲大小。需要与max_heap_table_size参数一起调整。
record_buffer
record_buffer每个进行顺序扫描的线程为其扫描的表分配一个缓冲区。如果做了很多顺序扫描,可以显示的改变该值
table_open_cache
mysql每打开一个表,都会读入一些数据到table_open_cache缓存中,当mysql在这个缓存中找不到相应的信息时,才会去磁盘读取
注:如果table_open_cache设置很大时,如果系统处理不了那么多文件描述符,那么就会出现客户端失效,连接不上。
mysql> show status like ‘Open%tables’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| Open_tables | 0 |
| Opened_tables | 0 |
+—————+——-+
2 rows in set (0.00 sec)
open_tables表示当前打开的表缓存数,如果执行flush tables操作,则此系统会关闭一些当前没有使用的表缓存而使得此状态值减小;
opend_tables表示曾经打开的表缓存数,会一直进行累加,如果执行flush tables操作,值不会减小。
thread_cache_size
默认值8,表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放在缓存中。如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空或者是新的请求那么这个线程将被重新创建,如果很多新的线程增加这个值可以改善系统的性能,根据物理内存设置如下规则:
1 | # 1G —> 8 |
语雀镜像 : my.cnf 参数调优 ,点此 提问
binlog 就是binary log,二进制日志文件,这个文件记录了MySQL所有的DML操作。通过binlog日志我们可以做数据恢复,增量备份,主主复制和主从复制等等。对于开发者可能对binlog并不怎么关注,但是对于运维或者架构人员来讲是非常重要的。
1 | [MATCH (col1,col2,...) AGAINST (expr [search_modifier])] |
MySQL has support for full-text indexing and searching:
-
A full-text index in MySQL is an index of type FULLTEXT
.
-
Full-text indexes can be used only with InnoDB
or MyISAM
tables, and can be created only for CHAR
, VARCHAR
, or TEXT
columns.
-
As of MySQL 5.7.6, MySQL
provides a built-in full-text ngram parser that supports Chinese, Japanese, and Korean (CJK), and an installable MeCab full-text parser plugin for Japanese. Parsing differences are outlined in “ngram Full-Text Parser” and “MeCab Full-Text Parser Plugin”
-
A FULLTEXT
index definition can be given in the CREATE TABLE
statement when a table is created, or added later using ALTER TABLE
or CREATE INDEX
.
-
For large data sets, it is much faster to load your data into a table that has no FULLTEXT
index and then create the index after that, than to load data into a table that has an existing FULLTEXT
index.
Full-text searching is performed using MATCH() ... AGAINST
syntax. MATCH()
takes a comma-separated list that names the columns to be searched. AGAINST
takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
There are three types of full-text searches:
-
A natural language search interprets the search string as a phrase in natural human language (a phrase in free text). There are no special operators. The stopword list applies. For more information about stopword lists, see[Section 13.9.4, “Full-Text Stopwords”].
Full-text searches are natural language searches if the IN NATURAL LANGUAGE MODE
modifier is given or if no modifier is given. For more information, see [Section 13.9.1, “Natural Language Full-Text Searches”].
-
A boolean search interprets the search string using the rules of a special query language. The string contains the words to search for. It can also contain operators that specify requirements such that a word must be present or absent in matching rows, or that it should be weighted higher or lower than usual. Certain common words (stopwords) are omitted from the search index and do not match if present in the search string. The IN BOOLEAN MODE
modifier specifies a boolean search. For more information, see [Section 13.9.2, “Boolean Full-Text Searches”].
-
A query expansion search is a modification of a natural language search. The search string is used to perform a natural language search. Then words from the most relevant rows returned by the search are added to the search string and the search is done again. The query returns the rows from the second search. The IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
or WITH QUERY EXPANSION
modifier specifies a query expansion search. For more information, see [Section 13.9.3, “Full-Text Searches with Query Expansion”].
For information about FULLTEXT
query performance, see [Section 9.3.4, “Column Indexes”].
For more information about InnoDB
FULLTEXT
indexes, see [Section 15.8.10, “InnoDB FULLTEXT Indexes”].
Constraints on full-text searching are listed in [Section 13.9.5, “Full-Text Restrictions”].
The [myisam_ftdump] utility dumps the contents of a MyISAM
full-text index. This may be helpful for debugging full-text queries. See [Section 5.6.2, “myisam_ftdump — Display Full-Text Index information”].
By default or with the IN NATURAL LANGUAGE MODE
modifier, the MATCH()
function performs a natural language search for a string against a text collection. A collection is a set of one or more columns included in a FULLTEXT
index. The search string is given as the argument to AGAINST()
. For each row in the table, MATCH()
returns a relevance value; that is, a similarity measure between the search string and the text in that row in the columns named in the MATCH()
list.
1 | mysql> CREATE TABLE articles ( |
By default, the search is performed in case-insensitive fashion. To perform a case-sensitive full-text search, use a binary collation for the indexed columns. For example, a column that uses the latin1
character set of can be assigned a collation of latin1_bin
to make it case sensitive for full-text searches.
When MATCH()
is used in a WHERE
clause, as in the example shown earlier, the rows returned are automatically sorted with the highest relevance first. Relevance values are nonnegative floating-point numbers. Zero relevance means no similarity. Relevance is computed based on the number of words in the row (document), the number of unique words in the row, the total number of words in the collection, and the number of rows that contain a particular word.
Note
The term “document” may be used interchangeably with the term “row”, and both terms refer to the indexed part of the row. The term “collection” refers to the indexed columns and encompasses all rows.
To simply count matches, you could use a query like this:
1 | mysql> SELECT COUNT(*) FROM articles |
You might find it quicker to rewrite the query as follows:
1 | mysql> SELECT |
The first query does some extra work (sorting the results by relevance) but also can use an index lookup based on the WHERE
clause. The index lookup might make the first query faster if the search matches few rows. The second query performs a full table scan, which might be faster than the index lookup if the search term was present in most rows.
For natural-language full-text searches, the columns named in the MATCH()
function must be the same columns included in some FULLTEXT
index in your table. For the preceding query, note that the columns named in the MATCH()
function (title
and body
) are the same as those named in the definition of the article
table’s FULLTEXT
index. To search the title
or body
separately, you would create separate FULLTEXT
indexes for each column.
You can also perform a boolean search or a search with query expansion. These search types are described in[Section 13.9.2, “Boolean Full-Text Searches”], and [Section 13.9.3, “Full-Text Searches with Query Expansion”].
A full-text search that uses an index can name columns only from a single table in the MATCH()
clause because an index cannot span multiple tables. For MyISAM
tables, a boolean search can be done in the absence of an index (albeit more slowly), in which case it is possible to name columns from multiple tables.
The preceding example is a basic illustration that shows how to use the MATCH()
function where rows are returned in order of decreasing relevance. The next example shows how to retrieve the relevance values explicitly. Returned rows are not ordered because the SELECT
statement includes neither WHERE
nor ORDER BY
clauses:
1 | mysql> SELECT id, MATCH (title,body) |
The following example is more complex. The query returns the relevance values and it also sorts the rows in order of decreasing relevance. To achieve this result, specify MATCH()
twice: once in the SELECT
list and once in theWHERE
clause. This causes no additional overhead, because the MySQL optimizer notices that the two MATCH()
calls are identical and invokes the full-text search code only once.
1 | mysql> SELECT id, body, MATCH (title,body) AGAINST |
The MySQL FULLTEXT
implementation regards any sequence of true word characters (letters, digits, and underscores) as a word. That sequence may also contain apostrophes ('
), but not more than one in a row. This means that aaa'bbb
is regarded as one word, but aaa''bbb
is regarded as two words. Apostrophes at the beginning or the end of a word are stripped by the FULLTEXT
parser; 'aaa'bbb'
would be parsed as aaa'bbb
.
The built-in FULLTEXT
parser determines where words start and end by looking for certain delimiter characters; for example, (space), ,
(comma), and .
(period). If words are not separated by delimiters (as in, for example, Chinese), the built-in FULLTEXT
parser cannot determine where a word begins or ends. To be able to add words or other indexed terms in such languages to a FULLTEXT
index that uses the built-in FULLTEXT
parser, you must preprocess them so that they are separated by some arbitrary delimiter such as "
. Alternatively, as of MySQL 5.7.6, you can create FULLTEXT
indexes using the ngram parser plugin (for Chinese, Japanese, or Korean) or the MeCab parser plugin (for Japanese).
It is possible to write a plugin that replaces the built-in full-text parser. For details, see [Section 26.2, “The MySQL Plugin API”]. For example parser plugin source code, see the plugin/fulltext
directory of a MySQL source distribution.
Some words are ignored in full-text searches:
-
Any word that is too short is ignored. The default minimum length of words that are found by full-text searches is three characters for InnoDB
search indexes, or four characters for MyISAM
. You can control the cutoff by setting a configuration option before creating the index: innodb_ft_min_token_size
configuration option for InnoDB
search indexes, or ft_min_word_len
for MyISAM
.
Note
This behavior does not apply to FULLTEXT
indexes that use the ngram parser. For the ngram parser, token length is defined by the ngram_token_size
option.
-
Words in the stopword list are ignored. A stopword is a word such as “the” or “some” that is so common that it is considered to have zero semantic value. There is a built-in stopword list, but it can be overridden by a user-defined list. The stopword lists and related configuration options are different for InnoDB
search indexes and MyISAM
ones. Stopword processing is controlled by the configuration options innodb_ft_enable_stopword
,innodb_ft_server_stopword_table
, and innodb_ft_user_stopword_table
for InnoDB
search indexes, andft_stopword_file
for MyISAM
ones.
See [Section 13.9.4, “Full-Text Stopwords”] to view default stopword lists and how to change them. The default minimum word length can be changed as described in [Section 13.9.6, “Fine-Tuning MySQL Full-Text Search”].
Every correct word in the collection and in the query is weighted according to its significance in the collection or query. Thus, a word that is present in many documents has a lower weight, because it has lower semantic value in this particular collection. Conversely, if the word is rare, it receives a higher weight. The weights of the words are combined to compute the relevance of the row. This technique works best with large collections.
MyISAM Limitation
For very small tables, word distribution does not adequately reflect their semantic value, and this model may sometimes produce bizarre results for search indexes on MyISAM
tables. For example, although the word “MySQL”is present in every row of the articles
table shown earlier, a search for the word in a MyISAM
search index produces no results:
1 | mysql> SELECT * FROM articles |
The search result is empty because the word “MySQL” is present in at least 50% of the rows, and so is effectively treated as a stopword. This filtering technique is more suitable for large data sets, where you might not want the result set to return every second row from a 1GB table, than for small data sets where it might cause poor results for popular terms.
The 50% threshold can surprise you when you first try full-text searching to see how it works, and makes InnoDB
tables more suited to experimentation with full-text searches. If you create a MyISAM
table and insert only one or two rows of text into it, every word in the text occurs in at least 50% of the rows. As a result, no search returns any results until the table contains more rows. Users who need to bypass the 50% limitation can build search indexes onInnoDB
tables, or use the boolean search mode explained in [Section 13.9.2, “Boolean Full-Text Searches”].
MySQL can perform boolean full-text searches using the IN BOOLEAN MODE
modifier. With this modifier, certain characters have special meaning at the beginning or end of words in the search string. In the following query, the +
and -
operators indicate that a word must be present or absent, respectively, for a match to occur. Thus, the query retrieves all the rows that contain the word “MySQL” but that do not contain the word “YourSQL”:
1 | mysql> SELECT * FROM articles WHERE MATCH (title,body) |
Note
In implementing this feature, MySQL uses what is sometimes referred to as implied Boolean logic, in which
-+
stands for AND
--
stands for NOT
-
[no operator] implies OR
Boolean full-text searches have these characteristics:
-
They do not automatically sort rows in order of decreasing relevance.
-InnoDB
tables require a FULLTEXT
index on all columns of the MATCH()
expression to perform boolean queries. Boolean queries against a MyISAM
search index can work even without a FULLTEXT
index, although a search executed in this fashion would be quite slow.
-
The minimum and maximum word length full-text parameters apply to FULLTEXT
indexes created using the built-in FULLTEXT
parser and MeCab parser plugin. innodb_ft_min_token_size
and innodb_ft_max_token_size
are used for InnoDB
search indexes. ft_min_word_len
and ft_max_word_len
are used for MyISAM
search indexes.
Minimum and maximum word length full-text parameters do not apply to FULLTEXT
indexes created using the ngram parser. ngram token size is defined by the ngram_token_size
option.
-
The stopword list applies, controlled by innodb_ft_enable_stopword
, innodb_ft_server_stopword_table
, and innodb_ft_user_stopword_table
for InnoDB
search indexes, and ft_stopword_file
for MyISAM
ones.
-InnoDB
full-text search does not support the use of multiple operators on a single search word, as in this example: '++apple'
. Use of multiple operators on a single search word returns a syntax error to standard out. MyISAM full-text search will successfully process the same search ignoring all operators except for the operator immediately adjacent to the search word.
-InnoDB
full-text search only supports leading plus or minus signs. For example, InnoDB
supports '+apple'
but does not support 'apple+'
. Specifying a trailing plus or minus sign causes InnoDB
to report a syntax error.
-InnoDB
full-text search does not support the use of a leading plus sign with wildcard ('+*'
), a plus and minus sign combination ('+-'
), or leading a plus and minus sign combination ('+-apple'
). These invalid queries return a syntax error.
-InnoDB
full-text search does not support the use of the @
symbol in boolean full-text searches. The @
symbol is reserved for use by the @distance
proximity search operator.
-
They do not use the 50% threshold that applies to MyISAM
search indexes.
The boolean full-text search capability supports the following operators:
-+
A leading or trailing plus sign indicates that this word must be present in each row that is returned. InnoDB
only supports leading plus signs.
--
A leading or trailing minus sign indicates that this word must not be present in any of the rows that are returned. InnoDB
only supports leading minus signs.
Note: The -
operator acts only to exclude rows that are otherwise matched by other search terms. Thus, a boolean-mode search that contains only terms preceded by -
returns an empty result. It does not return “all rows except those containing any of the excluded terms.”
-
(no operator)
By default (when neither +
nor -
is specified), the word is optional, but the rows that contain it are rated higher. This mimics the behavior of MATCH() ... AGAINST()
without the IN BOOLEAN MODE
modifier.
-@*
distance*
This operator works on InnoDB
tables only. It tests whether two or more words all start within a specified distance from each other, measured in words. Specify the search words within a double-quoted string immediately before the@*
distance*
operator, for example, MATCH(col1) AGAINST('"word1 word2 word3" @8' IN BOOLEAN MODE)
-> <
These two operators are used to change a word’s contribution to the relevance value that is assigned to a row. The>
operator increases the contribution and the <
operator decreases it. See the example following this list.
-( )
Parentheses group words into subexpressions. Parenthesized groups can be nested.
-~
A leading tilde acts as a negation operator, causing the word’s contribution to the row’s relevance to be negative. This is useful for marking “noise” words. A row containing such a word is rated lower than others, but is not excluded altogether, as it would be with the -
operator.
-*
The asterisk serves as the truncation (or wildcard) operator. Unlike the other operators, it is appended to the word to be affected. Words match if they begin with the word preceding the *
operator.
If a word is specified with the truncation operator, it is not stripped from a boolean query, even if it is too short or a stopword. Whether a word is too short is determined from the innodb_ft_min_token_size
setting for InnoDB
tables, or ft_min_word_len
for MyISAM
tables. These options are not applicable to FULLTEXT
indexes that use the ngram parser.
The wildcarded word is considered as a prefix that must be present at the start of one or more words. If the minimum word length is 4, a search for '+*
word* +the*'
could return fewer rows than a search for '+*
word* +the'
, because the second query ignores the too-short search term the
.
-"
A phrase that is enclosed within double quote ("
) characters matches only rows that contain the phrase literally, as it was typed. The full-text engine splits the phrase into words and performs a search in the FULLTEXT
index for the words. Nonword characters need not be matched exactly: Phrase searching requires only that matches contain exactly the same words as the phrase and in the same order. For example, "test phrase"
matches "test, phrase"
.
If the phrase contains no words that are in the index, the result is empty. The words might not be in the index because of a combination of factors: if they do not exist in the text, are stopwords, or are shorter than the minimum length of indexed words.
The following examples demonstrate some search strings that use boolean full-text operators:
-'apple banana'
Find rows that contain at least one of the two words.
-'+apple +juice'
Find rows that contain both words.
-'+apple macintosh'
Find rows that contain the word “apple”, but rank rows higher if they also contain “macintosh”.
-'+apple -macintosh'
Find rows that contain the word “apple” but not “macintosh”.
-'+apple ~macintosh'
Find rows that contain the word “apple”, but if the row also contains the word “macintosh”, rate it lower than if row does not. This is “softer” than a search for '+apple -macintosh'
, for which the presence of “macintosh” causes the row not to be returned at all.
-'+apple +(>turnover <strudel)'
Find rows that contain the words “apple” and “turnover”, or “apple” and “strudel” (in any order), but rank “apple turnover” higher than “apple strudel”.
-'apple*'
Find rows that contain words such as “apple”, “apples”, “applesauce”, or “applet”.
-'"some words"'
Find rows that contain the exact phrase “some words” (for example, rows that contain “some words of wisdom” but not “some noise words”). Note that the "
characters that enclose the phrase are operator characters that delimit the phrase. They are not the quotation marks that enclose the search string itself.
InnoDB
full-text search is modeled on the Sphinx full-text search engine, and the algorithms used are based onBM25 and TF-IDF ranking algorithms. For these reasons, relevancy rankings for InnoDB
boolean full-text search may differ from MyISAM
relevancy rankings.
InnoDB
uses a variation of the “term frequency-inverse document frequency” (TF-IDF
) weighting system to rank a document’s relevance for a given full-text search query. The TF-IDF
weighting is based on how frequently a word appears in a document, offset by how frequently the word appears in all documents in the collection. In other words, the more frequently a word appears in a document, and the less frequently the word appears in the document collection, the higher the document is ranked.
The term frequency (TF
) value is the number of times that a word appears in a document. The inverse document frequency (IDF
) value of a word is calculated using the following formula, where total_records
is the number of records in the collection, and matching_records
is the number of records that the search term appears in.
${IDF} = log10( ${total_records} / ${matching_records} )
When a document contains a word multiple times, the IDF value is multiplied by the TF value:
${TF} * ${IDF}
Using the TF
and IDF
values, the relevancy ranking for a document is calculated using this formula:
${rank} = ${TF} _ ${IDF} _ ${IDF}
The formula is demonstrated in the following examples.
This example demonstrates the relevancy ranking calculation for a single-word search.
1 | mysql> CREATE TABLE articles ( |
There are 8 records in total, with 3 that match the “database” search term. The first record (id 6
) contains the search term 6 times and has a relevancy ranking of 1.0886961221694946
. This ranking value is calculated using a TF
value of 6 (the “database” search term appears 6 times in record id 6
) and an IDF
value of 0.42596873216370745, which is calculated as follows (where 8 is the total number of records and 3 is the number of records that the search term appears in):
${IDF} = log10( 8 / 3 ) = 0.42596873216370745
The TF
and IDF
values are then entered into the ranking formula:
${rank} = ${TF} _ ${IDF} _ ${IDF}
Performing the calculation in the MySQL command-line client returns a ranking value of 1.088696164686938.
1 | mysql> SELECT 6*log10(8/3)*log10(8/3); |
Note
You may notice a slight difference in the ranking values returned by the SELECT ... MATCH ... AGAINST
statement and the MySQL command-line client (1.0886961221694946
versus 1.088696164686938
). The difference is due to how the casts between integers and floats/doubles are performed internally by InnoDB
(along with related precision and rounding decisions), and how they are performed elsewhere, such as in the MySQL command-line client or other types of calculators.
This example demonstrates the relevancy ranking calculation for a multiple-word full-text search based on thearticles
table and data used in the previous example.
If you search on more than one word, the relevancy ranking value is a sum of the relevancy ranking value for each word, as shown in this formula:
${rank} = ${TF} _ ${IDF} _ ${IDF} + ${TF} _ ${IDF} _ ${IDF}
Performing a search on two terms (‘mysql tutorial’) returns the following results:
1 | mysql> SELECT id, title, body, MATCH (title,body) AGAINST ('mysql tutorial' IN BOOLEAN MODE) |
In the first record (id 8
), ‘mysql’ appears once and ‘tutorial’ appears twice. There are six matching records for ‘mysql’ and two matching records for ‘tutorial’. The MySQL command-line client returns the expected ranking value when inserting these values into the ranking formula for a multiple word search:
1 | mysql> SELECT (1*log10(8/6)*log10(8/6)) + (2*log10(8/2)*log10(8/2)); |
Note
The slight difference in the ranking values returned by the SELECT ... MATCH ... AGAINST
statement and the MySQL command-line client is explained in the preceding example.
Full-text search supports query expansion (and in particular, its variant “blind query expansion”). This is generally useful when a search phrase is too short, which often means that the user is relying on implied knowledge that the full-text search engine lacks. For example, a user searching for “database” may really mean that “MySQL”, “Oracle”, “DB2”, and “RDBMS” all are phrases that should match “databases” and should be returned, too. This is implied knowledge.
Blind query expansion (also known as automatic relevance feedback) is enabled by adding WITH QUERY EXPANSION
or IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
following the search phrase. It works by performing the search twice, where the search phrase for the second search is the original search phrase concatenated with the few most highly relevant documents from the first search. Thus, if one of these documents contains the word “databases” and the word “MySQL”, the second search finds the documents that contain the word“MySQL” even if they do not contain the word “database”. The following example shows this difference:
1 | mysql> SELECT * FROM articles |
Another example could be searching for books by Georges Simenon about Maigret, when a user is not sure how to spell “Maigret”. A search for “Megre and the reluctant witnesses” finds only “Maigret and the Reluctant Witnesses”without query expansion. A search with query expansion finds all books with the word “Maigret” on the second pass.
Note
Because blind query expansion tends to increase noise significantly by returning nonrelevant documents, use it only when a search phrase is short.
The stopword list is loaded and searched for full-text queries using the server character set and collation (the values of the character_set_server
and collation_server
system variables). False hits or misses might occur for stopword lookups if the stopword file or columns used for full-text indexing or searches have a character set or collation different from character_set_server
or collation_server
.
Case sensitivity of stopword lookups depends on the server collation. For example, lookups are case insensitive if the collation is latin1_swedish_ci
, whereas lookups are case sensitive if the collation is latin1_general_cs
orlatin1_bin
.
InnoDB
has a relatively short list of default stopwords, because documents from technical, literary, and other sources often use short words as keywords or in significant phrases. For example, you might search for “to be or not to be” and expect to get a sensible result, rather than having all those words ignored.
To see the default InnoDB
stopword list, query the INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD
table.
1 | mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD; |
To define your own stopword list for all InnoDB
tables, define a table with the same structure as theINNODB_FT_DEFAULT_STOPWORD
table, populate it with stopwords, and set the value of theinnodb_ft_server_stopword_table
option to a value in the form *
db_name*/*
table_name*
before creating the full-text index. The stopword table must have a single VARCHAR
column named value
. The following example demonstrates creating and configuring a new global stopword table for InnoDB
.
– Create a new stopword table
1 | mysql> CREATE TABLE my_stopwords(value VARCHAR(30)) ENGINE = INNODB; |
– Insert stopwords (for simplicity, a single stopword is used in this example)
1 | mysql> INSERT INTO my_stopwords(value) VALUES ('Ishmael'); |
– Create the table
1 | mysql> CREATE TABLE opening_lines ( |
– Insert data into the table
1 | mysql> INSERT INTO opening_lines(opening_line,author,title) VALUES |
– Set the innodb_ft_server_stopword_table option to the new stopword table
1 | mysql> SET GLOBAL innodb_ft_server_stopword_table = 'test/my_stopwords'; |
– Create the full-text index (which rebuilds the table if no FTS_DOC_ID column is defined)
1 | mysql> CREATE FULLTEXT INDEX idx ON opening_lines(opening_line); |
Verify that the specified stopword (‘Ishmael’) does not appear by querying the words inINFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE
.
Note
By default, words less than 3 characters in length or greater than 84 characters in length do not appear in anInnoDB
full-text search index. Maximum and minimum word length values are configurable using theinnodb_ft_max_token_size
and innodb_ft_min_token_size
variables. This default behavior does not apply to the ngram parser plugin. ngram token size is defined by the ngram_token_size
option.
1 | mysql> SET GLOBAL innodb_ft_aux_table='test/opening_lines'; |
To create stopword lists on a table-by-table basis, create other stopword tables and use theinnodb_ft_user_stopword_table
option to specify the stopword table that you want to use before you create the full-text index.
The stopword file is loaded and searched using latin1
if character_set_server
is ucs2
, utf16
, utf16le
, or utf32
.
To override the default stopword list for MyISAM tables, set the ft_stopword_file
system variable. (See [Section 6.1.5, “Server System Variables”].) The variable value should be the path name of the file containing the stopword list, or the empty string to disable stopword filtering. The server looks for the file in the data directory unless an absolute path name is given to specify a different directory. After changing the value of this variable or the contents of the stopword file, restart the server and rebuild your FULLTEXT
indexes.
The stopword list is free-form, separating stopwords with any nonalphanumeric character such as newline, space, or comma. Exceptions are the underscore character (_
) and a single apostrophe ('
) which are treated as part of a word. The character set of the stopword list is the server’s default character set; see [Section 11.1.3.2, “Server Character Set and Collation”].
The following table shows the default list of stopwords for MyISAM
search indexes. In a MySQL source distribution, you can find this list in the storage/myisam/ft_static.c
file.
1 | | a's | able | about | above | according | |
-
Full-text searches are supported for InnoDB
and MyISAM
tables only.
-
Full-text searches are not supported for partitioned tables. See [Section 20.6, “Restrictions and Limitations on Partitioning”].
-
Full-text searches can be used with most multibyte character sets. The exception is that for Unicode, the utf8
character set can be used, but not the ucs2
character set. Although FULLTEXT
indexes on ucs2
columns cannot be used, you can perform IN BOOLEAN MODE
searches on a ucs2
column that has no such index.
The remarks for utf8
also apply to utf8mb4
, and the remarks for ucs2
also apply to utf16
, utf16le
, and utf32
.
-
Ideographic languages such as Chinese and Japanese do not have word delimiters. Therefore, the built-in full-text parser cannot determine where words begin and end in these and other such languages.
In MySQL 5.7.6, a character-based ngram full-text parser that supports Chinese, Japanese, and Korean (CJK), and a word-based MeCab parser plugin that supports Japanese are provided for use with InnoDB
and MySIAM
tables.
-
Although the use of multiple character sets within a single table is supported, all columns in a FULLTEXT
index must use the same character set and collation.
-
The MATCH()
column list must match exactly the column list in some FULLTEXT
index definition for the table, unless this MATCH()
is IN BOOLEAN MODE
on a MyISAM
table. For MyISAM
tables, boolean-mode searches can be done on nonindexed columns, although they are likely to be slow.
-
The argument to AGAINST()
must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
-
Index hints are more limited for FULLTEXT
searches than for non-FULLTEXT
searches. See [Section 9.9.4, “Index Hints”].
-
For InnoDB
, all DML operations (INSERT
, UPDATE
, DELETE
) involving columns with full-text indexes are processed at transaction commit time. For example, for an INSERT
operation, an inserted string is tokenized and decomposed into individual words. The individual words are then added to full-text index tables when the transaction is committed. As a result, full-text searches only return committed data.
-
The ‘%’ character is not a supported wildcard character for full-text searches.
MySQL’s full-text search capability has few user-tunable parameters. You can exert more control over full-text searching behavior if you have a MySQL source distribution because some changes require source code modifications. See [Section 2.9, “Installing MySQL from Source”].
Full-text search is carefully tuned for effectiveness. Modifying the default behavior in most cases can actually decrease effectiveness. Do not alter the MySQL sources unless you know what you are doing.
Most full-text variables described in this section must be set at server startup time. A server restart is required to change them; they cannot be modified while the server is running.
Some variable changes require that you rebuild the FULLTEXT
indexes in your tables. Instructions for doing so are given later in this section.
The minimum and maximum lengths of words to be indexed are defined by the innodb_ft_min_token_size
andinnodb_ft_max_token_size
for InnoDB
search indexes, and ft_min_word_len
and ft_max_word_len
forMyISAM
ones.
Note
Minimum and maximum word length full-text parameters do not apply to FULLTEXT
indexes created using the ngram parser. ngram token size is defined by the ngram_token_size
option.
After changing any of these options, rebuild your FULLTEXT
indexes for the change to take effect. For example, to make two-character words searchable, you could put the following lines in an option file:
1 | [mysqld] |
Then restart the server and rebuild your FULLTEXT
indexes. For MyISAM
tables, note the remarks regarding[myisamchk] in the instructions that follow for rebuilding MyISAM
full-text indexes.
For MyISAM
search indexes, the 50% threshold for natural language searches is determined by the particular weighting scheme chosen. To disable it, look for the following line in storage/myisam/ftdefs.h
:
1 | #define GWS_IN_USE GWS_PROB |
Change that line to this:
1 | #define GWS_IN_USE GWS_FREQ |
Then recompile MySQL. There is no need to rebuild the indexes in this case.
Note
By making this change, you severely decrease MySQL’s ability to provide adequate relevance values for the MATCH()
function. If you really need to search for such common words, it would be better to search using IN BOOLEAN MODE
instead, which does not observe the 50% threshold.
To change the operators used for boolean full-text searches on MyISAM
tables, set the ft_boolean_syntax
system variable. (InnoDB
does not have an equivalent setting.) This variable can be changed while the server is running, but you must have the SUPER
privilege to do so. No rebuilding of indexes is necessary in this case. See[Section 6.1.5, “Server System Variables”], which describes the rules governing how to set this variable.
For the built-in full-text parser, you can change the set of characters that are considered word characters in several ways, as described in the following list. After making the modification, rebuild the indexes for each table that contains any FULLTEXT
indexes. Suppose that you want to treat the hyphen character (‘-‘) as a word character. Use one of these methods:
-
Modify the MySQL source: In storage/innobase/handler/ha_innodb.cc
(for InnoDB
), or instorage/myisam/ftdefs.h
(for MyISAM
), see the true_word_char()
and misc_word_char()
macros. Add '-'
to one of those macros and recompile MySQL.
-
Modify a character set file: This requires no recompilation. The true_word_char()
macro uses a “character type”table to distinguish letters and numbers from other characters. . You can edit the contents of the <ctype><map>
array in one of the character set XML files to specify that '-'
is a “letter.” Then use the given character set for yourFULLTEXT
indexes. For information about the <ctype><map>
array format, see [Section 11.3.1, “Character Definition Arrays”].
-
Add a new collation for the character set used by the indexed columns, and alter the columns to use that collation. For general information about adding collations, see [Section 11.4, “Adding a Collation to a Character Set”]. For an example specific to full-text indexing, see [Section 13.9.7, “Adding a Collation for Full-Text Indexing”].
If you modify full-text variables that affect indexing (innodb_ft_min_token_size
, innodb_ft_max_token_size
,innodb_ft_server_stopword_table
, innodb_ft_user_stopword_table
, innodb_ft_enable_stopword
,ngram_token_size
you must rebuild your FULLTEXT
indexes after making the changes. Modifying theinnodb_ft_min_token_size
, innodb_ft_max_token_size
, or ngram_token_size
variables, which cannot be set dynamically, require restarting the server and rebuilding the indexes.
To rebuild the FULLTEXT
indexes for an InnoDB
table, use ALTER TABLE
with the DROP INDEX
and ADD INDEX
options to drop and re-create each index.
Running OPTIMIZE TABLE
on a table with a full-text index rebuilds the full-text index, removing deleted Document IDs and consolidating multiple entries for the same word, where possible.
To optimize a full-text index, enable innodb_optimize_fulltext_only
and run OPTIMIZE TABLE
.
1 | mysql> set GLOBAL innodb_optimize_fulltext_only=ON; |
To avoid lengthy rebuild times for full-text indexes on large tables, you can use theinnodb_ft_num_word_optimize
option to perform the optimization in stages. Theinnodb_ft_num_word_optimize
option defines the number of words that are optimized each time OPTIMIZE TABLE
is run. The default setting is 2000, which means that 2000 words are optimized each time OPTIMIZE TABLE
is run. Subsequent OPTIMIZE TABLE
operations continue from where the preceding OPTIMIZE TABLE
operation ended.
If you modify full-text variables that affect indexing (ft_min_word_len
, ft_max_word_len
, or ft_stopword_file
), or if you change the stopword file itself, you must rebuild your FULLTEXT
indexes after making the changes and restarting the server.
To rebuild the FULLTEXT
indexes for a MyISAM
table, it is sufficient to do a QUICK
repair operation:
1 | mysql> REPAIR TABLE *`tbl_name`* QUICK; |
Alternatively, use ALTER TABLE
as just described. In some cases, this may be faster than a repair operation.
Each table that contains any FULLTEXT
index must be repaired as just shown. Otherwise, queries for the table may yield incorrect results, and modifications to the table will cause the server to see the table as corrupt and in need of repair.
If you use [myisamchk] to perform an operation that modifies MyISAM
table indexes (such as repair or analyze), theFULLTEXT
indexes are rebuilt using the default full-text parameter values for minimum word length, maximum word length, and stopword file unless you specify otherwise. This can result in queries failing.
The problem occurs because these parameters are known only by the server. They are not stored in MyISAM
index files. To avoid the problem if you have modified the minimum or maximum word length or stopword file values used by the server, specify the same ft_min_word_len
, ft_max_word_len
, and ft_stopword_file
values for[myisamchk] that you use for [mysqld]. For example, if you have set the minimum word length to 3, you can repair a table with [myisamchk] like this:
shell> myisamchk –recover –ft_min_word_len=3 tbl_name
.MYI
To ensure that [myisamchk] and the server use the same values for full-text parameters, place each one in both the [mysqld]
and [myisamchk]
sections of an option file:
1 | [mysqld] |
An alternative to using [myisamchk] for MyISAM
table index modification is to use the REPAIR TABLE
, ANALYZE TABLE
, OPTIMIZE TABLE
, or ALTER TABLE
statements. These statements are performed by the server, which knows the proper full-text parameter values to use.
This section describes how to add a new collation for full-text searches using the built-in full-text parser. The sample collation is like latin1_swedish_ci
but treats the '-'
character as a letter rather than as a punctuation character so that it can be indexed as a word character. General information about adding collations is given in [Section 11.4, “Adding a Collation to a Character Set”]; it is assumed that you have read it and are familiar with the files involved.
To add a collation for full-text indexing, use this procedure:
1.
Add a collation to the Index.xml
file. The collation ID must be unused, so choose a value different from 1000 if that ID is already taken on your system.
2.
Declare the sort order for the collation in the latin1.xml
file. In this case, the order can be copied fromlatin1_swedish_ci
:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49
44 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF
41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49
44 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF
3.
Modify the ctype
array in latin1.xml
. Change the value corresponding to 0x2D (which is the code for the '-'
character) from 10 (punctuation) to 01 (small letter). In the following array, this is the element in the fourth row down, third value from the end.
00
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48 10 10 10 10 10 10 10 10 10 10 10 10 01 10 10
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
4.
Restart the server.
5.
To employ the new collation, include it in the definition of columns that are to use it:
1 | mysql> DROP TABLE IF EXISTS t1; |
6.Test the collation to verify that hyphen is considered as a word character:
1 | mysql> INSERT INTO t1 VALUEs ('----'),('....'),('abcd'); |
The built-in MySQL full-text parser uses the white space between words as a delimiter to determine where words begin and end, which is a limitation when working with ideographic languages that do not use word delimiters. To address this limitation, MySQL provides an ngram full-text parser that supports Chinese, Japanese, and Korean (CJK). The ngram full-text parser is supported for use with InnoDB
and MyISAM
.
Note
MySQL also provides a MeCab full-text parser plugin for Japanese, which tokenizes documents into meaningful words. For more information, see [Section 13.9.9, “MeCab Full-Text Parser Plugin”].
An ngram is a contiguous sequence of n
characters from a given sequence of text. The ngram parser tokenizes a sequence of text into a contiguous sequence of n
characters. For example, you can tokenize “abcd” for different values of n
using the ngram full-text parser.
n=1: ‘a’, ‘b’, ‘c’, ‘d’
n=2: ‘ab’, ‘bc’, ‘cd’
n=3: ‘abc’, ‘bcd’
n=4: ‘abcd’
The ngram full-text parser, introduced in MySQL 5.7.6, is a built-in server plugin. As with other built-in server plugins, it is automatically loaded when the server is started.
The full-text search syntax described in [Section 13.9, “Full-Text Search Functions”] applies to the ngram parser plugin. Differences in parsing behavior are described in this section. Full-text-related configuration options, except for minimum and maximum word length options (innodb_ft_min_token_size
, innodb_ft_max_token_size
,ft_min_word_len
, ft_max_word_len
) are also applicable.
The ngram parser has a default ngram token size of 2 (bigram). For example, with a token size of 2, the ngram parser parses the string “abc def” into four tokens: “ab”, “bc”, “de” and “ef”.
ngram token size is configurable using the ngram_token_size
configuration option, which has a minimum value of 1 and maximum value of 10.
Typically, ngram_token_size
is set to the size of the largest token that you want to search for. If you only intend to search for single characters, set ngram_token_size
to 1. A smaller token size produces a smaller full-text search index, and faster searches. If you need to search for words comprised of more than one character, setngram_token_size
accordingly. For example, “Happy Birthday” is “生日快乐” in simplified Chinese, where “生日” is “birthday”, and “快乐” translates as “happy”. To search on two-character words such as these, setngram_token_size
to a value of 2 or higher.
As a read-only variable, ngram_token_size
may only be set as part of a startup string or in a configuration file:
1 | mysqld --ngram_token_size=2 |
1 | [mysqld] |
Note
The following minimum and maximum word length configuration options are ignored for FULLTEXT
indexes that use the ngram parser: innodb_ft_min_token_size
, innodb_ft_max_token_size
, ft_min_word_len
, andft_max_word_len
.
To create a FULLTEXT
index that uses the ngram parser, specify WITH PARSER ngram
with CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
.
The following example demonstrates creating a table with an ngram
FULLTEXT
index, inserting sample data (Simplified Chinese text), and viewing tokenized data in the INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
table.
1 | mysql> USE test; |
To add a FULLTEXT
index to an existing table, you can use ALTER TABLE
or CREATE INDEX
. For example:
1 | CREATE TABLE articles ( |
Or:
1 | CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER ngram; |
The ngram parser eliminates spaces when parsing. For example:
-
“ab cd” is parsed to “ab”, “cd”
-
“a bc” is parsed to “bc”
The built-in MySQL full-text parser compares words to entries in the stopword list. If a word is equal to an entry in the stopword list, the word is excluded from the index. For the ngram parser, stopword handling is performed differently. Instead of excluding tokens that are equal to entries in the stopword list, the ngram parser excludes tokens that contain stopwords. For example, assuming ngram_token_size=2
, a document that contains “a,b” is parsed to “a,” and “,b”. If a comma (“,”) is defined as a stopword, both “a,” and “,b” are excluded from the index because they contain a comma.
By default, the ngram parser uses the default stopword list, which contains a list of English stopwords. For a stopword list applicable to Chinese, Japanese, or Korean, you must create your own. For information about creating a stopword list, see [Section 13.9.4, “Full-Text Stopwords”].
Stopwords greater in length than ngram_token_size
are ignored.
For natural language mode search, the search term is converted to a union of ngram terms. For example, the string “abc” (assuming ngram_token_size=2
) is converted to “ab bc”. Given two documents, one containing “ab” and the other containing “abc”, the search term “ab bc” matches both documents.
For boolean mode search, the search term is converted to an ngram phrase search. For example, the string ‘abc’ (assuming ngram_token_size=2
) is converted to ‘“ab bc”’. Given two documents, one containing ‘ab’ and the other containing ‘abc’, the search phrase ‘“ab bc”’ only matches the document containing ‘abc’.
Because an ngram FULLTEXT
index contains only ngrams, and does not contain information about the beginning of terms, wildcard searches may return unexpected results. The following behaviors apply to wildcard searches using ngram FULLTEXT
search indexes:
-
If the prefix term of a wildcard search is shorter than ngram token size, the query returns all indexed rows that contain ngram tokens starting with the prefix term. For example, assuming ngram_token_size=2
, a search on “a*”returns all rows starting with “a”.
-
If the prefix term of a wildcard search is longer than ngram token size, the prefix term is converted to an ngram phrase and the wildcard operator is ignored. For example, assuming ngram_token_size=2
, an “abc*” wildcard search is converted to “ab bc”.
Phrase searches are converted to ngram phrase searches. For example, The search phrase “abc” is converted to“ab bc”, which returns documents containing “abc” and “ab bc”.
The search phrase “abc def” is converted to “ab bc de ef”, which returns documents containing “abc def” and “ab bc de ef”. A document that contains “abcdef” is not returned.
The built-in MySQL full-text parser uses the white space between words as a delimiter to determine where words begin and end, which is a limitation when working with ideographic languages that do not use word delimiters. To address this limitation for Japanese, MySQL provides a MeCab full-text parser plugin. The MeCab full-text parser plugin is supported for use with InnoDB
and MyISAM
.
Note
MySQL also provides an ngram full-text parser plugin that supports Japanese. For more information, see[Section 13.9.8, “ngram Full-Text Parser”].
The MeCab full-text parser plugin, introduced in MySQL 5.7.6, is a full-text parser plugin for Japanese that tokenizes a sequence of text into meaningful words. For example, MeCab tokenizes “データベース管理” (“Database Management”) into “データベース” (“Database”) and “管理” (“Management”). By comparison, the [ngram] full-text parser tokenizes text into a contiguous sequence of n
characters, where n
represents a number between 1 and 10.
In addition to tokenizing text into meaningful words, MeCab indexes are typically smaller than ngram indexes, and MeCab full-text searches are generally faster. One drawback is that it may take longer for the MeCab full-text parser to tokenize documents, compared to the ngram full-text parser.
The full-text search syntax described in [Section 13.9, “Full-Text Search Functions”] applies to the MeCab parser plugin. Differences in parsing behavior are described in this section. Full-text related configuration options are also applicable.
For additional information about the MeCab parser, refer to the MeCab Documentation on the Google Developerssite.
The MeCab parser plugin requires mecab
and mecab-ipadic
.
On supported Fedora, Debian and Ubuntu platforms (except Ubuntu 12.04 where the system mecab
version is too old), MySQL dynamically links to the system mecab
installation if it is installed to the default location. On other supported Unix-like platforms, libmecab.so
is statically linked in libpluginmecab.so
, which is located in the MySQL plugin directory. mecab-ipadic
is included in MySQL binaries and is located in *
MYSQL_HOME*\lib\mecab
.
You can install mecab
and mecab-ipadic
using a native package management utility (on Fedora, Debian, and Ubuntu), or you can build mecab
and mecab-ipadic
from source. For information about installing mecab
andmecab-ipadic
using a native package management utility, see [Installing MeCab From a Binary Distribution (Optional)]”). If you want to build mecab
and mecab-ipadic
from source, see [Building MeCab From Source (Optional)]”).
On Windows, libmecab.dll
is found in the MySQL bin
directory. mecab-ipadic
is located in*
MYSQL_HOME*/lib/mecab
.
To install and configure the MeCab parser plugin, perform the following steps:
1.
In the MySQL configuration file, set the mecab_rc_file
configuration option to the location of the mecabrc
configuration file, which is the configuration file for MeCab. If you are using the MeCab package distributed with MySQL, the mecabrc
file is located in MYSQL_HOME/lib/mecab/etc/
.
1 | [mysqld] |
The loose
prefix is an [option modifier]. The mecab_rc_file
option is not recognized by MySQL until the MeCaB parser plugin is installed but it must be set before attempting to install the MeCaB parser plugin. The loose
prefix allows you restart MySQL without encountering an error due to an unrecognized variable.
If you use your own MeCab installation, or build MeCab from source, the location of the mecabrc
configuration file may differ.
For information about the MySQL configuration file and its location, see [Section 5.2.6, “Using Option Files”].
2.
Also in the MySQL configuration file, set the minimum token size to 1 or 2, which are the values recommended for use with the MeCab parser. For InnoDB
tables, minimum token size is defined by the innodb_ft_min_token_size
configuration option, which has a default value of 3. For MyISAM
tables, minimum token size is defined by ft_min_word_len
, which has a default value of 4.
[mysqld]
innodb_ft_min_token_size=1
3.
Modify the mecabrc
configuration file to specify the dictionary you want to use. The mecab-ipadic
package distributed with MySQL binaries includes three dictionaries (ipadic_euc-jp
, ipadic_sjis
, and ipadic_utf-8
). The mecabrc
configuration file packaged with MySQL contains and entry similar to the following:
dicdir = /path/to/mysql/lib/mecab/lib/mecab/dic/ipadic_euc-jp
To use the ipadic_utf-8
dictionary, for example, modify the entry as follows:
dicdir=MYSQL_HOME
/lib/mecab/dic/ipadic_utf-8
If you are using your own MeCab installation or have built MeCab from source, the default dicdir
entry in the mecabrc
file will differ, as will the dictionaries and their location.
Note
After the MeCab parser plugin is installed, you can use the mecab_charset
status variable to view the character set used with MeCab. The three MeCab dictionaries provided with the MySQL binary support the following character sets.
-
The ipadic_euc-jp
dictionary supports the ujis
and eucjpms
character sets.
-
The ipadic_sjis
dictionary supports the sjis
and cp932
character sets. cp932
support was added in MySQL 5.7.7.
-
The ipadic_utf-8
dictionary supports the utf8
and utf8mb4
character sets. utf8mb4
support was added in MySQL 5.7.7.
mecab_charset``ipadic_utf-8``utf8``utf8mb4``mecab_charset``utf8
4.
Restart MySQL.
5.
Install the MeCab parser plugin:
The MeCab parser plugin is installed using INSTALL PLUGIN
syntax. The plugin name is mecab
, and the shared library name is libpluginmecab.so
. For additional information about installing plugins, see [Section 6.5.2, “Installing and Uninstalling Plugins”].
INSTALL PLUGIN mecab SONAME ‘libpluginmecab.so’;
Once installed, the MeCab parser plugin loads at every normal MySQL restart.
6.
Verify that the MeCab parser plugin is loaded using the SHOW PLUGINS
statement.
1 | mysql> SHOW PLUGINS; |
A mecab
plugin should appear in the list of plugins.
To create a FULLTEXT
index that uses the mecab parser, specify WITH PARSER ngram
with CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
.
This example demonstrates creating a table with a mecab
FULLTEXT
index, inserting sample data, and viewing tokenized data in the INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
table:
1 | mysql> USE test; |
To add a FULLTEXT
index to an existing table, you can use ALTER TABLE
or CREATE INDEX
. For example:
1 | CREATE TABLE articles ( |
Or:
1 | CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER mecab; |
The MeCab parser uses spaces as separators in query strings. For example, the MeCab parser tokenizes ‘データベース管理’ as ‘データベース’ and ‘管理’.
By default, the MeCab parser uses the default stopword list, which contains a short list of English stopwords. For a stopword list applicable to Japanese, you must create your own. For information about creating stopword lists, see[Section 13.9.4, “Full-Text Stopwords”].
For natural language mode search, the search term is converted to a union of tokens. For example, ‘データベース管理’ is converted to ‘データベース 管理’ .
1 | SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース管理' IN NATURAL LANGUAGE MODE); |
For boolean mode search, the search term is converted to a search phrase. For example, ‘データベース管理’ is converted to ‘“データベース 管理”‘.
1 | SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース管理' IN BOOLEAN MODE); |
Wildcard search terms are not tokenized. A search on ‘データベース管理*’ is performed on the prefix, ‘データベース管理’.
1 | SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース*' IN BOOLEAN MODE); |
Phrases are tokenized. For example, “データベース管理” is tokenized as “データベース 管理”.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST(‘“データベース管理”‘ IN BOOLEAN MODE);
This section describes how to install mecab
and mecab-ipadic
from a binary distribution using a native package management utility. For example, on Fedora, you can use Yum to perform the installation:
1 | yum mecab-devel |
On Debian or Ubuntu, you can perform an APT installation:
1 | apt-get install mecab |
If you want to build mecab
and mecab-ipadic
from source, basic installation steps are provided below. For additional information, refer to the MeCab documentation.
1.
Download the tar.gz packages for mecab
and mecab-ipadic
from http://taku910.github.io/mecab/#download. As of February, 2016, the latest available packages are mecab-0.996.tar.gz
and mecab-ipadic-2.7.0-20070801.tar.gz
.
2.
Install mecab
:
1 | tar zxfv mecab-0.996.tar |
3.
Install mecab-ipadic
:
1 | tar zxfv mecab-ipadic-2.7.0-20070801.tar |
4.
Compile MySQL using the WITH_MECAB
CMake option. Set the WITH_MECAB
option to system
if you have installedmecab
and mecab-ipadic
to the default location.
-DWITH_MECAB=system
If you defined a custom installation directory, set WITH_MECAB
to the custom directory. For example:
-DWITH_MECAB=/path/to/mecab
语雀镜像 : [mysql] 13.9 Full-Text 搜索函数 ,点此 提问
事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
删除的SQL语句
模式 | 描述 |
---|---|
. | 匹配任意单个字符 |
[] | 匹配括号内的任何字符, 也可以匹配一定范围的字符, [0-9] 数字 |
* | 匹配该符号前面字符的零个或多个实例 |
+ | 匹配该符号前面字符的一个或多个实例 |
? | 匹配该符号前面字符的零个或多个 |
^ | 跟在符号后边的内容必须为值的开头 |
$ | 跟在符号前边的内容必须为值的结尾 |
| | 或匹配 |
{n} | 重复N次 |
{n,m} | n-m次 |