← Home ← Codex ← DEBT
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 36
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 1 ping S 1 ping M 0 pings T 0 pings W 1 ping T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 2 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Google 7 Perplexity 6 Ahrefs 3 Unknown AI 2 Meta AI 2 ChatGPT 2 SEMrush 2 Scrapy 2 Claude 1 Majestic 1 PetalBot 1
crawler 26 crawler_json 3
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
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Low ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant