13.9 · Reading query plans, typing and NULL, WAL locking, savepoints and full-text search
SQLite is small and forgiving, which is why its surprises are expensive: a constraint that is not enforced, a filter that cannot use an index, a lock you did not expect.
Mental model. Ask SQLite what it plans to do (EXPLAIN QUERY PLAN), turn on the checks you rely on (STRICT tables, constraints), and treat transactions as the unit of correctness and speed.
Plans and defaults
Index use in query plans, and the typing and NULL rules people assume.
- How do you read EXPLAIN QUERY PLAN, and which common query shapes stop SQLite using an index?
EXPLAIN QUERY PLAN SELECT … returns one line per step, and the first word tells you the cost: SEARCH … USING INDEX is an index lookup (fast), SCAN reads the… - How does SQLite’s dynamic typing and three-valued NULL logic bite: affinity, STRICT tables, IN and NOT IN?
Typing is dynamic. A column’s declared type is an affinity, not a constraint: in the check an INTEGER column accepts the string 'abc' (stored as text), the…
Concurrency and search
WAL locking, savepoints and constraint failures, and FTS5.
- How does write-ahead logging change locking, what does SQLITE_BUSY mean, and how do you configure busy handling and transactions?
The default journal mode is delete (a rollback journal); PRAGMA journal_mode = WAL switches to a write-ahead log and the mode is persistent in the file (the… - How do savepoints and constraint failures behave inside a transaction, and when do you use FTS5 instead of LIKE?
A transaction makes several statements all-or-nothing and much faster (one commit instead of one per statement, which in a loop of thousands of inserts is the…
More in Persistence & data
- 13.1 · Where data belongs, and the Keychain
- 13.2 · SQLite fundamentals: transactions, WAL, constraints, indexes and migrations
- 13.3 · The Core Data stack, contexts and faults, concurrency, and migrations
- 13.4 · SwiftData: models, contexts, predicates, actors and schema evolution
- 13.5 · The repository pattern and cache design
- 13.6 · Crashes mid-write, integrity, backups and data protection
- 13.7 · Syncing data across devices: conflicts, tombstones and CloudKit
- 13.8 · UserDefaults surprises and FileManager essentials
- 13.10 · Merge conflicts, faults and batch requests, delete rules, and the SwiftData context
- 13.11 · Keychain status codes, detecting corruption, an LRU cache and library trade-offs