未加索引的where条件会导致全表扫描,使查询慢十倍;需用explain确认索引使用情况,复合索引字段顺序影响生效范围,低区分度字段不宜单独建索引,order by需索引支持,大offset分页应改用游标分页。

WHERE 条件字段没加索引,查询直接变慢十倍
大数据量表里,SELECT * FROM orders WHERE user_id = 123 这种查询如果 user_id 没索引,MySQL 或 PostgreSQL 就得全表扫描。几千万行?可能要几秒甚至十几秒——而加了索引通常压到几十毫秒。
实操建议:
- 先用
EXPLAIN看执行计划,重点盯type字段:要是ALL,基本就是全扫;ref或range才算走索引 - 复合索引要注意字段顺序:
CREATE INDEX idx_status_user ON orders(status, user_id)能加速WHERE status = 'paid' AND user_id = 123,但对WHERE user_id = 123单独查几乎无效 - 别给低区分度字段单独建索引,比如
is_deleted TINYINT(99% 是 0),优化器大概率直接弃用
ORDER BY + LIMIT 在无索引时会触发 filesort
SELECT * FROM logs ORDER BY created_at DESC LIMIT 20 看似简单,但如果 created_at 没索引,数据库就得把几百万行全读出来、内存排序、再取前 20——内存爆掉或磁盘临时文件都会拖垮性能。
实操建议:
- 带
ORDER BY的分页查询,必须确保排序字段在索引最左侧,且和查询条件能复用同一个索引 - 避免
OFFSET大值分页:OFFSET 100000会让数据库先跳过 10 万行,即使有索引也慢;改用游标分页(如WHERE created_at ) - PostgreSQL 中
ORDER BY ... NULLS LAST会影响索引使用,建索引时得显式写成CREATE INDEX ON logs(created_at DESC NULLS LAST)
索引太多反而拖慢写入,尤其高并发 INSERT/UPDATE 场景
每多一个索引,每次 INSERT 就得多写一份 B+ 树结构;UPDATE 如果改的是索引列,还要同步更新多个索引页。单表上百个索引?写入吞吐可能掉一半以上。
数据本地化解决接口缓存数据无限增加,读取慢的问题,速度极大提升更注重SEO优化优化了系统的SEO,提升网站在搜索引擎的排名,增加网站爆光率搜索框本地化不用远程读取、IFRAME调用,更加容易应用及修改增加天气预报功能页面增加了天气预报功能,丰富内容增加点评和问答页面增加了点评和问答相关页面,增强网站粘性电子地图优化优化了电子地图的加载速度与地图功能酒店列表增加房型读取酒店列表页可以直接展示房型,增
实操建议:
- 用
information_schema.STATISTICS查哪些索引从没被用过(结合performance_schema.table_io_waits_summary_by_index_usage,MySQL 8.0+) - 唯一性不强的字段组合慎建唯一索引,比如
(region, category, status)可能重复率高,但加了UNIQUE会导致插入冲突或锁等待加剧 - 考虑部分索引(PostgreSQL)或条件索引(MySQL 8.0.13+):只索引活跃数据,例如
CREATE INDEX idx_active_orders ON orders(user_id) WHERE status IN ('pending', 'processing')
TEXT/BLOB 字段不能直接建普通索引,容易报错或失效
ALTER TABLE articles ADD INDEX idx_content(content) 在 MySQL 里会报错 ERROR 1170 (42000): BLOB/TEXT column 'content' used in key specification without a key length;就算强行指定长度(如 content(255)),也可能因截断导致查询不准。
实操建议:
- 全文检索场景用
FULLTEXT索引(MySQL)或tsvector+GIN(PostgreSQL),别硬套 B-tree - 想按前缀快速过滤?提取特征字段单独存,比如加一列
content_hash CHAR(16)存 MD5 前 16 位,再对它建索引 - JSON 字段别直接索引整个字段,MySQL 支持
GENERATED COLUMN提取路径值并建索引,例如ALTER TABLE events ADD COLUMN event_type VARCHAR(32) AS (data->>'$.type'),再建INDEX idx_event_type ON events(event_type)
索引不是越多越好,也不是建了就一定生效;关键看查询模式是否匹配索引结构,以及写入负载能不能扛住额外开销。最常被忽略的是:上线前没用真实数据量 + 真实流量压测索引效果,结果大促时才发现某个看似合理的索引根本没被优化器选中。









