Databases 12 min read

Master MySQL Full-Text Search: Inverted Indexes, Queries, and Best Practices

This article explains how MySQL's InnoDB engine implements full‑text search using inverted indexes, shows how to create and use full‑text indexes with various query modes, demonstrates Boolean operators and query expansion, and covers index removal techniques.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Master MySQL Full-Text Search: Inverted Indexes, Queries, and Best Practices

Inverted Index

Full‑text search usually relies on an inverted index, which maps words to the documents (or positions) where they appear. Two common forms are:

inverted file index: {word, document IDs}

full inverted index: {word, (document ID, position)}

图片
图片

The inverted file index stores each word with the IDs of documents containing it, enabling quick retrieval of matching documents. The full inverted index also records the exact position of each word within a document, using more space but allowing precise location‑based queries.

图片
图片

Full‑Text Search

Create Full‑Text Index

1. Create a table with a full‑text index:

<code>CREATE TABLE table_name ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, author VARCHAR(200), title VARCHAR(200), content TEXT(500), FULLTEXT full_index_name (col_name) ) ENGINE=InnoDB;</code>

2. Add a full‑text index to an existing table:

<code>CREATE FULLTEXT INDEX full_index_name ON table_name(col_name);</code>

Using Full‑Text Index

MySQL supports full‑text queries on InnoDB or MyISAM tables for CHAR, VARCHAR, and TEXT columns using the MATCH() AGAINST() syntax.

<code>MATCH(col1,col2,...) AGAINST(expr [search_modifier])</code>

Search modifiers include:

IN NATURAL LANGUAGE MODE

IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION

IN BOOLEAN MODE

WITH QUERY EXPANSION

Natural Language

Natural language mode interprets the query as a phrase in human language.

<code>SELECT count(*) AS count FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('MySQL');</code>
<code>SELECT count(IF(MATCH (title, body) AGAINST ('MySQL'), 1, NULL)) AS count FROM `fts_articles`;</code>

You can also retrieve relevance scores:

<code>SELECT *, MATCH (title, body) AGAINST ('MySQL') AS Relevance FROM fts_articles;</code>

Boolean

Boolean mode uses operators to control word presence and relevance.

+ : word must be present

- : word must be absent

(no operator) : word is optional but boosts relevance if present

@distance : proximity search (e.g., MATCH(context) AGAINST('"Pease hot"@30' IN BOOLEAN MODE) )

* : wildcard for word prefixes

"..." : exact phrase

Examples:

<code>SELECT * FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);</code>
图片
图片
<code>SELECT * FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('MySQL IBM' IN BOOLEAN MODE);</code>
图片
图片
<code>SELECT * FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('"DB2 IBM"@3' IN BOOLEAN MODE);</code>
图片
图片
<code>SELECT * FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('+MySQL +(&gt;database &lt;DBMS)' IN BOOLEAN MODE);</code>
图片
图片
<code>SELECT * FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('MySQL ~database' IN BOOLEAN MODE);</code>
图片
图片
<code>SELECT * FROM `fts_articles` WHERE MATCH (title, body) AGAINST ('"MySQL Security"' IN BOOLEAN MODE);</code>
图片
图片

Query Expansion

Query expansion modifies natural language search to include related terms when the original keyword is short or ambiguous.

<code>-- Create index
create FULLTEXT INDEX title_body_index on fts_articles(title,body);

-- Natural Language query
SELECT * FROM `fts_articles` WHERE MATCH(title,body) AGAINST('database');

-- With query expansion
SELECT * FROM `fts_articles` WHERE MATCH(title,body) AGAINST('database' WITH QUERY expansion);</code>
图片
图片
图片
图片

Because query expansion can return many irrelevant results, it should be used with caution.

Delete Full‑Text Index

1. Drop the index directly:

<code>DROP INDEX full_idx_name ON db_name.table_name;</code>

2. Use ALTER TABLE:

<code>ALTER TABLE db_name.table_name DROP INDEX full_idx_name;</code>

Conclusion

This article combined theory and practice to introduce MySQL full‑text indexes, covering their structure, creation, query modes, advanced operators, query expansion, and removal.

SQLDatabaseQuery OptimizationMySQLInverted IndexFull-Text Search
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.