MySQL Cheatsheet
At a glance
| What it is | Popular open source relational database (Oracle), InnoDB storage engine by default |
| Use it for | Web/OLTP apps (LAMP, WordPress, Laravel), read-heavy workloads with replicas |
| Latest stable | Innovation 26.10.0 (released 2026-10-20); LTS 9.7.4 and 8.4.13 (released 2026-10-20) - checked 2026-10-31 |
| Release tracks | LTS (8.4, 9.7): long support, bug/security fixes only. Innovation (now calendar versions YY.MM, e.g. 26.10): new features roughly quarterly. 8.0 reached end of life in April 2026 |
| Official docs | dev.mysql.com/doc - 8.4 release notes - 9.7 release notes - 26.10 release notes |
Core concepts
- Server -> database (= schema) -> table:
DATABASEandSCHEMAare synonyms in MySQL - InnoDB: transactional, row-level locking, MVCC, foreign keys, crash recovery; avoid MyISAM
- Clustered primary key: InnoDB stores rows in PK order; secondary indexes point to the PK, so keep the PK small
- Isolation: default
REPEATABLE READ(with gap/next-key locks), unlike PostgreSQL'sREAD COMMITTED - Character set:
utf8mb4is the default (8.0+);utf8/utf8mb3cannot store emoji - SQL mode:
STRICT_TRANS_TABLES(default) rejects bad data instead of silently truncating - Replication: binary log based source -> replica, async or semi-sync; Group Replication / InnoDB Cluster for HA
- Users: identified by
'user'@'host'; default auth plugincaching_sha2_password
Syntax & commands
mysql -h 127.0.0.1 -P 3306 -u root -p # connect (prompts for password)
mysql -u app -p app_db < schema.sql # run a script
mysqldump --single-transaction --routines --triggers app_db > app_db.sql
mysql -u root -p app_db < app_db.sql # restore
mysqlsh # MySQL Shell (JS/Python/SQL modes, dump utilities)
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 \
-v mysqldata:/var/lib/mysql mysql:8.4 # LTS image tag
SHOW DATABASES; CREATE DATABASE app CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
USE app; SHOW TABLES;
DESCRIBE users; SHOW CREATE TABLE users\G
SHOW INDEX FROM users; SHOW PROCESSLIST;
SELECT VERSION(); SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
CREATE TABLE users (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
settings JSON,
status ENUM('active', 'banned') NOT NULL DEFAULT 'active',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_users_email (email),
KEY idx_users_status_created (status, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Upsert
INSERT INTO users (email, name) VALUES ('a@x.io', 'Ann') AS new
ON DUPLICATE KEY UPDATE name = new.name; -- row alias, 8.0.19+ (VALUES() is deprecated)
-- JSON
SELECT name, settings->>'$.theme' AS theme FROM users
WHERE JSON_CONTAINS(settings, '"beta"', '$.flags');
UPDATE users SET settings = JSON_SET(settings, '$.theme', 'dark') WHERE id = 1;
-- Pagination
SELECT * FROM users ORDER BY id LIMIT 20 OFFSET 40;
-- Users and privileges
CREATE USER 'app'@'%' IDENTIFIED BY 'change-me';
GRANT SELECT, INSERT, UPDATE, DELETE ON app.* TO 'app'@'%';
SHOW GRANTS FOR 'app'@'%';
ALTER USER 'app'@'%' IDENTIFIED BY 'new-secret';
DROP USER 'app'@'%';
-- Query plans
EXPLAIN FORMAT=TREE SELECT * FROM users WHERE email = 'a@x.io';
EXPLAIN ANALYZE SELECT * FROM users WHERE status = 'active' ORDER BY created_at DESC LIMIT 10;
Common patterns
-- Online schema change (most ADD COLUMN / ADD INDEX are online in InnoDB)
ALTER TABLE users ADD COLUMN phone VARCHAR(30), ALGORITHM=INSTANT;
ALTER TABLE users ADD INDEX idx_users_name (name), ALGORITHM=INPLACE, LOCK=NONE;
-- Full-text search
ALTER TABLE posts ADD FULLTEXT INDEX ft_posts (title, body);
SELECT * FROM posts WHERE MATCH(title, body) AGAINST('+mysql -oracle' IN BOOLEAN MODE);
-- Window functions + CTEs (8.0+)
WITH ranked AS (
SELECT id, user_id, total,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
FROM orders
)
SELECT * FROM ranked WHERE rn = 1; -- latest order per user
-- Job queue
SELECT * FROM jobs WHERE status = 'queued' ORDER BY id LIMIT 10 FOR UPDATE SKIP LOCKED;
-- Find slow queries
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SELECT * FROM sys.statements_with_runtimes_in_95th_percentile LIMIT 10;
-- Table sizes
SELECT table_name, ROUND((data_length + index_length) / 1024 / 1024, 1) AS size_mb
FROM information_schema.tables WHERE table_schema = 'app' ORDER BY size_mb DESC;
Gotchas
- Identifiers are quoted with backticks (
`order`); double quotes are strings unlessANSI_QUOTESis on - Table name case sensitivity follows the OS (
lower_case_table_names), so Linux and Windows/macOS can differ - Default collation
utf8mb4_0900_ai_ciis case- and accent-insensitive:'a' = 'A'and'e' = 'é'are true FULL OUTER JOINis not supported; emulate withLEFT JOIN ... UNION ... RIGHT JOINTIMESTAMPis limited to 2038 and converts time zones;DATETIMEdoes not- Implicit type conversion in
WHERE varchar_col = 123disables the index; compare with the right type - Avoid
SELECT ... LIMITwith bigOFFSETon large tables; use keyset pagination (WHERE id > ?) mysqldumpwithout--single-transactionlocks tables; for big databases use MySQL Shell dump utilities- Upgrades go LTS -> LTS (8.4 -> 9.7) or along the Innovation track; from 8.0 go to 8.4 first
- Old terms changed: use
SOURCE/REPLICA(SHOW REPLICA STATUS,CHANGE REPLICATION SOURCE TO), not master/slave
What's new in recent releases
- MySQL 26.10 Innovation (2026-10-20): calendar versioning with
VERSION_WITH_UPDATE(); Health Monitor and the WebAuthn authentication plugin come to Community Edition; MySQL REST Service can run as a server component (release notes) - MySQL 9.7 LTS (9.7.0 on 2026-04-21): second LTS line; Community Edition gets DML (insert/update/delete) on JSON duality views, Hypergraph Optimizer access, OpenTelemetry telemetry and replication flow-control monitoring (9.7.0 notes)
- 9.x Innovation features now in LTS:
VECTORdata type, JavaScript stored programs (Enterprise Edition),EXPLAIN FORMAT=JSON ... INTO @var - MySQL 8.4 LTS:
mysql_native_passworddisabled by default, old master/slave replication statements removed in favor of source/replica - MySQL 8.0 reached end of life in April 2026 (last release 8.0.46): plan an upgrade to 8.4 or 9.7