← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

MySQL FULLTEXT Search

Database Intermediate
debt(d5/e3/b3/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), because the detection_hints list Semgrep as the tool for catching the LIKE '%keyword%' pattern on TEXT/VARCHAR columns — this is a SAST-level tool, not a default linter, meaning it requires deliberate setup to detect the misuse.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), grounded in the quick_fix which says 'Create a FULLTEXT index on searchable columns and use MATCH...AGAINST instead of LIKE '%keyword%'' — this is slightly more than a one-line swap (requires an ALTER TABLE to add the index plus query replacement) but is still a localised change within one component rather than a cross-cutting refactor.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), because the choice applies only to web contexts (per applies_to) and the misconception/common_mistakes are specific to search box functionality. Misuse (staying with LIKE scans) taxes only the search-related queries/components, not the broader codebase or architecture.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5), because the misconception states developers believe MySQL FULLTEXT is equivalent to Elasticsearch — a documented gotcha that many developers eventually learn. Additionally, common_mistakes include the silent exclusion of short words (ft_min_word_len) and no fuzzy matching, both of which are non-obvious behaviours that contradict reasonable expectations.

About DEBT scoring →

Also Known As

MySQL FULLTEXT MATCH AGAINST MySQL full text search PHP

TL;DR

A built-in MySQL search engine supporting natural language and boolean full-text queries on TEXT and VARCHAR columns.

Explanation

FULLTEXT indexes enable MATCH(col) AGAINST('query') syntax. Natural language mode ranks results by relevance. Boolean mode supports operators: +required, -excluded, *wildcard, "phrase". Minimum word length (ft_min_word_len, default 4) affects which words are indexed — short words like 'PHP' are excluded unless the config is changed. InnoDB FULLTEXT is available since MySQL 5.6. For complex search needs, Elasticsearch or MeiliSearch provide better relevance tuning, tokenisation, and multilingual support.

Common Misconception

MySQL FULLTEXT search is equivalent to Elasticsearch. MySQL FULLTEXT lacks advanced features like stemming, faceted search, and distributed indexing — use Elasticsearch for large-scale or multilingual search.

Why It Matters

LIKE '%keyword%' requires a full table scan and cannot rank results by relevance. FULLTEXT search is index-backed and returns relevance scores, making it suitable for search boxes on medium-sized datasets.

Common Mistakes

  • Searching for words shorter than ft_min_word_len (default 4) — they're excluded from the index silently.
  • Using FULLTEXT on MyISAM tables — works, but no transactions; prefer InnoDB.
  • Expecting FULLTEXT to handle typos or fuzzy matching — it doesn't without external preprocessing.

Avoid When

  • Do not use MySQL FULLTEXT for large-scale or multilingual search — use Elasticsearch or MeiliSearch.
  • Do not expect FULLTEXT to match words shorter than ft_min_word_len (default 4) — 'PHP' will not match.

When To Use

  • Use FULLTEXT for search boxes on medium-sized datasets (under a few million rows).
  • Use boolean mode when users need exact control — required terms (+), excluded terms (-), wildcards (*).

Code Examples

✗ Vulnerable
-- LIKE full table scan — no relevance ranking
SELECT * FROM articles WHERE body LIKE '%php security%'; -- slow, no ranking
✓ Fixed
-- Create FULLTEXT index
CREATE FULLTEXT INDEX idx_search ON articles (title, body);

-- Natural language search (relevance ranked)
SELECT id, title,
       MATCH(title, body) AGAINST('php security' IN NATURAL LANGUAGE MODE) AS score
FROM articles
WHERE MATCH(title, body) AGAINST('php security' IN NATURAL LANGUAGE MODE)
ORDER BY score DESC
LIMIT 20;

-- Boolean mode (exact control)
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('+php +security -deprecated' IN BOOLEAN MODE);

Added 31 Mar 2026
Views 116
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 1 ping T 2 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 2 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 2 pings W 0 pings T
No pings yet today
PetalBot 1 Bing 1
Google 14 PetalBot 10 Ahrefs 7 Perplexity 6 SEMrush 6 ChatGPT 5 Amazonbot 5 Unknown AI 3 Bing 3 Meta AI 2 Claude 2 Scrapy 2 Majestic 2 Applebot 2 Twitter/X 1
crawler 66 crawler_json 4
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
Database database A database is an organized collection of data stored electronically, designed so programs can efficiently retrieve, add, update, and delete information.

Nearly every application needs to remember information between sessions. Databases provide the reliable, fast, and organized storage that makes persistent data possible at any scale.

💡 Always use prepared statements with placeholders—never concatenate user input directly into database queries.

Ask Codex about Database →
DEV INTEL Tools & Severity
⚙ Fix effort: Medium
⚡ Quick Fix
Create a FULLTEXT index on searchable columns and use MATCH...AGAINST instead of LIKE '%keyword%'
📦 Applies To
web
🔗 Prerequisites
🔍 Detection Hints
LIKE '%keyword%' on TEXT/VARCHAR columns
Auto-detectable: ✓ Yes semgrep
🤖 AI Agent
Confidence: Medium False Positives: Low ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant