## 使用覆盖索引避免回表查询
覆盖索引包含查询所需的所有列,从而实现仅索引扫描(Index-Only Scan),完全跳过表数据读取。
**错误做法(索引扫描 + 堆表获取):**
sql
create index users_email_idx on users (email);
-- 必须从堆表中获取 name 和 created_at
select email, name, created_at from users where email = '
[email protected]';
**正确做法(使用 INCLUDE 的仅索引扫描):**
sql
-- 将非搜索列包含在索引中
create index users_email_idx on users (email) include (name, created_at);
-- 所有列均由索引提供,无需访问表
select email, name, created_at from users where email = '
[email protected]';
对于 SELECT 中需要但不需要过滤的列,请使用 INCLUDE:
sql
-- 按 status 搜索,但也需要 customer_id 和 total
create index orders_status_idx on orders (status) include (customer_id, total);
select status, customer_id, total from orders where status = 'shipped';
参考:[仅索引扫描 (Index-Only Scans)](https://www.postgresql.org/docs/current/indexes-index-only-scans.html)