索引是一种数据结构(通常是 B-tree),允许数据库无需扫描整个表就能快速找到行——类似于书的索引。它可以大幅加快对索引列的查询、筛选、联接和排序速度,但代价是额外的存储和更缓慢的写入。
索引如何帮助
users email ;
INDEX idx_users_email users(email);
没有索引时,数据库会执行全表扫描(检查每一行)。有了索引,它会在 B-tree 中导航,以对数时间找到匹配的行——这是扫描数百万行与少数几次查找之间的区别。
✓ Columns in WHERE clauses (frequently filtered)
✓ Columns used in JOINs (foreign keys especially)
✓ Columns in ORDER BY (sorting can use the index)
✓ Columns with high SELECTIVITY (many distinct values — email, id)
✓ Primary keys (auto-indexed) and unique constraints
✗ Columns rarely queried — wasted storage and write overhead
✗ Small tables — a full scan is already fast; an index adds no benefit
✗ Low-selectivity columns (e.g. a boolean with 2 values) — index barely helps
✗ Write-heavy columns — EVERY INSERT/UPDATE/DELETE must also update the indexes
→ too many indexes SLOW DOWN writes significantly
索引不是免费的:它们消耗存储空间并减慢写入速度(每次修改都必须更新索引)。过度索引会损害写入性能。
CREATE INDEX idx_users_country_name ON users(country, name); -- COMPOSITE (multi-column)
-- helps WHERE country = ? AND name = ?, and WHERE country = ? (leftmost prefix)
-- but NOT WHERE name = ? alone (order matters!)
CREATE UNIQUE INDEX ... -- enforces uniqueness
-- also: partial indexes, covering indexes, GIN/GiST (Postgres) for special data
索引是数据库性能中最重要的主题之一——它们是加快查询的主要工具,了解何时以及如何使用它们对于在大规模数据库上工作的任何人来说都是必不可少的知识。
核心价值是显著的:没有索引时,对列进行筛选、联接或排序的查询需要全表扫描(检查每一行——随着数据增长,速度会变得糟糕),而索引将这些转变为快速的对数查找——通常是查询耗时毫秒与秒或分钟的区别。
理解何时建立索引(频繁筛选的 WHERE 列、JOIN/外键列、ORDER BY 列、高选择性列)是查询性能的基础。
同样重要的是理解权衡和何时不建立索引:索引消耗存储空间,更重要的是,减慢写入速度(每个 INSERT/UPDATE/DELETE 都必须更新所有索引),因此过度索引会损害写入性能,而索引对小表或低选择性列的帮助很小。
这种平衡——对查询内容建立索引,同时避免过度索引——是一项关键技能。
了解复合索引(多列,其中列顺序对于它们帮助哪些查询很重要)可以完善实际索引知识。
由于查询性能对实际应用至关重要,而适当的索引(在正确的列上有正确的索引,平衡读取速度与写入成本和存储空间)是影响最大的数据库优化,掌握索引——它们的工作原理、何时使用它们、写入/存储权衡以及复合索引——是高性能数据库的核心、高价值知识,也是最重要和最常见的数据库测试主题之一。