让我们从一个经典的错误开始:将所有东西都索引化的方法。这是一个诱人的策略,不是吗?如果一个索引能加速查询,那么十个索引肯定能让我们的数据库飞起来!哦,天真无邪的孩子……

这里有一个快速的例子,说明这种方法如何可能出错:


CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50),
    email VARCHAR(100),
    created_at TIMESTAMP,
    last_login TIMESTAMP,
    status VARCHAR(20)
);

CREATE INDEX idx_username ON users(username);
CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_created_at ON users(created_at);
CREATE INDEX idx_last_login ON users(last_login);
CREATE INDEX idx_status ON users(status);

看起来无害,对吧?错了。这种索引狂热可能导致:

  • INSERT、UPDATE 和 DELETE 操作变慢,因为每个索引都需要更新
  • 磁盘空间使用增加
  • 查询优化器可能会混淆,并可能选择次优的执行计划

记住,朋友们:索引就像香料。要谨慎使用,以增强数据库的风味,而不是压倒它。

复合索引的难题

接下来是我们的反模式游行:误解复合索引的工作原理。我见过开发人员为 WHERE 子句中的每一列创建单独的索引,却没有意识到复合索引中列的顺序比灭霸的无限宝石更重要。

考虑这个查询:


SELECT * FROM orders
WHERE status = 'shipped'
AND created_at > '2023-01-01'
AND total_amount > 100;

你可能会想创建三个单独的索引:


CREATE INDEX idx_status ON orders(status);
CREATE INDEX idx_created_at ON orders(created_at);
CREATE INDEX idx_total_amount ON