SQL 格式化 / 优化分析器 / 结构可视化
SELECT
*
FROM
users u
WHERE
DATE(u.created_at) = '2025-01-01'
AND u.name LIKE '%john%'
AND u.id IN (
SELECT
user_id
FROM
orders
WHERE
total > 100
)
ORDER BY
RAND ()
LIMIT
10000, 20;Optimization Analysis
HIGHLeading-wildcard LIKE '%xxx' — index killer
A pattern starting with % cannot use a B-tree index, forcing a full table scan.
Suggestion: Use trailing wildcard "xxx%" if possible; for fuzzy full-text search use a fulltext index or Elasticsearch.
- L4:
LIKE '%john%' AND u.id IN (SELECT user
HIGHORDER BY RAND() — severe perf issue
RAND() forces a full scan + full sort with random keys. Slow at any meaningful table size.
Suggestion: Pick a random offset upfront or pre-compute random IDs at the application layer.
- L6:
ORDER BY RAND() LIMIT 10000, 20;
HIGHFunction wrapping a column in WHERE
WHERE DATE(created_at) = ... defeats the index on created_at — every row gets evaluated.
Suggestion: Rewrite as a range: WHERE created_at >= ... AND created_at < ...; or add a generated column / functional index.
- L3:
WHERE DATE(u.created_at) = '2025-01-01' AND u.name LIKE '%
HIGHLarge OFFSET (deep pagination)
LIMIT 10000, 20 still scans+skips the first 10000 rows. Slows down linearly with depth.
Suggestion: Switch to cursor pagination: WHERE id > <last_seen_id> LIMIT 20 — constant cost regardless of page.
- L7:
LIMIT 10000, 20
MIDSELECT *
Fetching every column adds I/O and network cost, prevents covering-index optimizations, and couples callers to schema changes.
Suggestion: Spell out only the columns you need: SELECT id, name, email FROM users.
- L1:
SELECT * FROM users u WHERE DATE(u.created_at) = '2025-01-01
MIDIN (SELECT ...) subquery
Some engines plan IN-subqueries as semi-joins, but older versions fall back to per-row execution.
Suggestion: Rewrite as JOIN: SELECT a.* FROM a JOIN b ON a.id = b.a_id — gives the planner more freedom.
- L5:
IN (SELECT user_id FROM orders WHERE total > 100) ORDER BY R
SQL Structure Visualization
*
usersas umainDATE(u.created_at) = '2025-01-01'u.name LIKE '%john%'u.id IN ((子查询))RAND()ASC20OFFSET10000