避坑指南

1. 善用“索引(Index)”——查字典的目录

  • 生活场景:给你一本 1000 页的字典,让你找“张三”这个词。如果你从第一页翻到最后一页(这在数据库里叫全表扫描),会累死。但如果你去查字典前几页的拼音目录,就能瞬间定位到在哪一页。

  • 数据库优化:如果你经常需要根据 email 去登录查找用户,那你就必须给 email 这一列加一个“目录”,在数据库里叫索引(Index)。

SQLAlchemy 怎么写
非常简单,在定义列的时候加上 index=True

1
2
# 优化后的写法:给 email 加上索引
email: Mapped[str] = mapped_column(String(50), index=True)

注意:目录不是越多越好。字典如果每页都是目录,字典就太厚了。只有经常被当作查询条件的列才加索引。

2. 只拿需要的列,别贪心(避免 SELECT * )

  • 不好的习惯
1
2
3
# 这会把用户的所有信息(包括头像、简介、密码等大文本)全部捞出来
user = session.execute(select(User).where(User.name == "张三")).scalar_one()
print(user.email)
  • 优化后:如果你只需要邮箱,就只单独要邮箱。
1
2
3
4
from sqlalchemy import select

# 明确指定只拿 User.email 这一列,速度会快很多
email = session.execute(select(User.email).where(User.name == "张三")).scalar()

3. 大名鼎鼎的 “N+1问题”(最容易踩的巨坑)

当你涉及两张表联合查询时(比如查“用户”以及“他所有的订单”),小白最容易写出让数据库崩溃的代码。

  • 错误的查法(N+1次点击)
    系统先查出 100 个用户(1次查询),然后用一个 Python 循环,挨个去查这 100 个用户的订单(100次查询)。为了点个名,一共折腾了数据库 101 次!

  • 聪明的查法(一次性搞定)
    告诉 SQLAlchemy:“我查用户的时候,顺便把他们的订单在一张表里连起来带出来!”(专业术语叫 joinedload 或 JOIN)。