如何解决合成索引中的OR问题
| 在我的许多查询中,我遇到的情况是SELECT * from myTable m
where m.userId = :userId
AND (m.to = :contactNumber OR m.from = :contactNumber)
AND .....
所以我为(userId,to,from)制作了一个复合索引
如果将OR
替换为AND
,则效果很好,但如果是OR
,则仅将索引用于userId
。
我有点困惑为什么会发生这种情况,还有没有更好的方法对此进行索引以提高性能,可能是将它们全部单独索引?
解决方法
合成索引可搜索几件混在一起的东西。将其视为串联的各个列的索引可能会有所帮助。
因此,如果使用or,则正在寻找userid和to或OR userid from的组合。但不是所有3个都在一起!
这有点取决于内容和全部,但是您可以为两个“ sub”查询添加两个组合(因此,userid和+以及+ userid和from)。但是userid索引不够吗?如果这样会使您的行减少到足以使其可管理的程度,那么我就不会添加各种复合索引...
, 您只需要考虑如何将综合索引组合在一起。键将主要在
userId
上排序。在每个userId
中,它们将按to
进行排序,在每个组中,它们将按from
进行排序。
这意味着,尽管您可以使用该索引查找特定的userId
值,userId:to
对和userId:to:from
三元组,但是查找特定的userId:from
对并不太好。这是因为这些值将在索引顺序中位于许多不同的位置,因为to
是比from
更高级的键。
一种方法是在userId:from
上放置一个额外的索引,然后在联合中使用两个单独的查询,这两个查询都可以使用自己的索引来有效地查找行。就像是:
select * from myTable m
where m.userId = :userId and m.to = :contactNumber
union
select * from myTable m
where m.userId = :userId and m.from = :contactNumber
第一个查询很可能会使用原始索引,因为ѭ10是它的两个顶级组件。您也可以为此指定一个索引,但是由于您已经有了一个可用的索引,所以它可能不是必需的(并且该索引可用于您希望包含所有三个组成部分的行的其他查询)。
第二个查询可能会使用新索引来有效地查找其行。
union
将组合两个查询并删除重复的查询。这与原始查询的意图匹配。如果您知道查询之间可能没有交叉,则可以使用union all
跳过(不必要的)重复删除步骤,但是我认为您不能在此处执行此操作。
该方法还具有潜在的优势,即在支持它的数据库中容易受到并行性的影响(查询可以并行运行,并且在两个查询完成后就可以合并)。
现在请记住,这是一般性建议。我本人是一个DB2专家,所以我在这里提出的内容是基于有关数据库内部工作方式的一般知识,而不是有关MySQL的细节。
您仍然应该测试查询以确保它们按预期方式工作(但是即使我是MySQL的作者,我也想这样做)。换句话说,我已经不知道我在这里说过多少遍了,算了,不要猜测!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。