表是orders
;每个 orders
可以有多个打开/关闭的 userid
。
-
WHERE userid = ? AND is_open = 1
将受益于以下任一“复合”索引:INDEX(userid,is_open)
或 INDEX(is_open,user_id)
。选择哪个更好取决于其他查询可能从哪个查询中受益更多。
-
将“关闭”的订单移到另一个表当然是一个有效的选择。这将有助于提高性能。 (我通常不推荐它,只是因为在少数情况下需要移动行和/或搜索两个表所需的笨拙代码。)
-
我认为 UNIQUE(id,userid)
没有优势。大概 id
因为是 PRIMARY KEY
已经“独一无二”了?此外,在复合索引中,将首先检查第一列;这就是PK已经在做的事情。
-
另一种方法... AUTO_INCREMENT
PK 导致数据 BTree 大致按时间顺序排列。但是您通常通过 userid
进入桌子?为了提高效率,请将 PRIMARY KEY(id),INDEX(userid)
更改为 PRIMARY KEY(userid,id),INDEX(id)
。 (但是……在不知道涉及此表的其他查询的情况下,我不能说这是否会提供很大的整体改进。)
-
这可能会更好:
PRIMARY KEY(userid,is_open,-- to benefit many queries
INDEX(id) -- to keep AUTO_INCREMENT happy
-
额外索引的成本(关于写操作的性能)通常可以通过 Selects 的加速来补偿。
,
在 id
和 user_id
上设置唯一索引不会给您带来任何好处,因为 id
已经被唯一索引为主键,并且无论如何都不会出现在您的查询中。
将关闭的订单移动到不同的表会带来一些性能改进,但由于关闭的订单可能分布在整个表中,因此性能改进不会像您预期的那样大。它还带来了管理开销,需要定期移动订单,以及报告的额外复杂性。
您最好的解决方案可能是在 user_id
上添加索引,以便 MySQL 可以直接转到所需的用户 ID 并仅搜索那些行。通过在 user_id
和 is_open
上建立索引,您可能会得到进一步的提升,但额外的好处可能很小。
请记住,每个额外的索引都会导致每次表更新时的性能损失。如果您的桌子不忙,这不会成为问题。
本文链接:https://www.f2er.com/7078.html