分离数据或使用 UNIQUE 索引进行优化

Segregating data or using UNIQUE index for optimization

我有一个table;

Orders
* id INT NN AN PK
* userid INT NN
* is_open TINYINT NN DEFAULT 1
* amount INT NN
* desc VARCHAR(255)

和我 运行 经常查询 SELECT * FROM orders WHERE userid = ? AND is_open = 1;。我想为此查询优化数据库,目前我有两个选择;

我不知道后者的表现如何,我知道前者会有助于提高性能,但我不知道这是否是最佳实践的好方法。

任何其他想法将不胜感激。

iduser_id 上设置唯一索引不会给您带来任何好处,因为 id 已经被唯一索引为主键,并且无论如何都不会出现在您的查询中.

将关闭的订单移动到不同的 table 会带来一些性能提升,但由于关闭的订单可能分布在整个 table,性能提升不会像您想象的那么大预计。它还会产生管理开销,需要定期移动订单,并增加报告的复杂性。

您最好的解决方案可能是在 user_id 上添加索引,以便 MySQL 可以直接转到所需的用户 ID 并仅搜索那些行。通过在 user_idis_open 上建立索引,您可能会得到进一步的提升,但额外的好处可能很小。

请记住,每次 table 更新时,每个额外的索引都会导致性能下降。如果您的 table 不忙,这不会有问题。

table属于orders;每个 userid.

可以有多个 open/closed orders
  • WHERE userid = ? AND is_open = 1 将从这些 'composite' 索引中受益:INDEX(userid, is_open)INDEX(is_open, user_id)。选择哪个更好取决于其他 查询可能比另一个查询更受益。

  • 将“已关闭”订单移至另一个 table 当然是一个有效的选择。这将有助于提高性能。 (我通常不推荐它,只是因为在少数需要的情况下移动行 and/or 以搜索两个 table 需要笨拙的代码。)

  • 我认为 UNIQUE(id, userid) 没有优势。大概 id 因为是 PRIMARY KEY 已经“独一无二”了?此外,在复合索引中,将首先检查第一列;这就是 PK 已经在做的事情。

  • 另一种方法... AUTO_INCREMENT PK 导致数据 BTree 大致按时间顺序排列。但是你平时伸手到table被userid?为了提高效率,将 PRIMARY KEY(id), INDEX(userid) 更改为 PRIMARY KEY(userid, id), INDEX(id)。 (但是...不知道 other 查询涉及这个 table,我不能说这是否会提供很多 overall 改进.)

  • 这可能会更好:

      PRIMARY KEY(userid, is_open, id),  -- to benefit many queries
      INDEX(id)   -- to keep AUTO_INCREMENT happy
    
  • 额外索引的成本(在写操作的性能上)通常被 Selects 的加速所补偿。