ker*_*lin 5 mysql database indexing performance
我正在寻找关于如何考虑表所需的最小索引数量的指导,在该表中,您在同一列列上执行不同的查询组合.理想情况下,您的答案将从这个具体示例中抽象出一些经验法则(如果可能的话).
此项目符号列表表示通常在我的表上执行的三种不同查询条件:
注意:user_id(int),race_type(varchar),recordable_id(int),recordable_type(varchar),active(boolean)
我可以为每个索引创建单独的多列索引,但是您的DB性能专家可能会以不同的方式处理它.
如果我需要提供更多信息以获得最佳答案,请告诉我们.
如果您的条件是分层的(如您的示例中所示),则可以使用组合索引.DBMS无法同时处理多个索引.虽然有可能并且他们试图充分利用这种情况.
这并不会改变您应该尝试为某个where子句创建特定索引的事实.如果可以将更多的WHERE索引组合到一个索引中,那么就可以释放一些空间和CPU周期.
让我们从为每个WHERE指定一个索引开始:
index1 (race_type, recordable_type, active)
index2 (race_type, recordable_id, recordable_type, active)
index3 (user_id, race_type, recordable_id, recordable_type, active)
Run Code Online (Sandbox Code Playgroud)
通常,您可以通过提升基数来优化订单.基数是列在数据集中可能具有的值的数量.在你的例子中active是一个布尔值.(请注意,boolean只有两个值的事实并不重要.int 如果你知道它只有两个值:0和1).
您的active字段的低基数意味着通过单个查找,我们可以消除一半可能的记录(当然,取决于您的数据集).完成此步骤后,您的第一个索引将如下所示:
index1 (active, race_type, recordable_type)
Run Code Online (Sandbox Code Playgroud)
除了基数之外,您还应该注意字段之间的任何逻辑层次结构.我不知道这些名字究竟是什么意思,我猜测某些种族类型会有自己的记录. - 这不会消除可记录与多种种类一起使用的可能性,但是你必须选择一个订单,这似乎更合乎逻辑.- 所以我们将使用race_type,recordable_type订单.
现在让我们来看看第二个指数.你介绍过recordable_id这里.在不知道您的数据集的情况下,我可以安全地假设recordable_id的基数将是比recordable_type更高的基数.换句话说,会有更多的id而不是类型.我还怀疑类型和id之间的层次结构(闻起来像一对多).所以让我们把它放在类型之后:
index2 (active, race_type, recordable_type, recordable_id)
Run Code Online (Sandbox Code Playgroud)
现在是时候关注另一个重要的角度了.修改数据库时,索引在硬盘上有自己的成本(实际上是免费的)和CPU周期.可以从左到右使用任何索引的子集.index2基本上包含index1它index1 + recordable_id,所以你可以摆脱它,最终只有一个.
一路走来user_id.作为一个ID字段,它表示高基数(许多可能的值),但请注意,"基数越高,后者的基数越高" 这一规则就越不规则.我们宁愿使用基数作为信标来帮助发现字段之间的层次结构关系.(并缩小索引大小).
是否user_id指向我们正在寻找的数据的个体参赛者(许多可能性)?或者是上传数据的客户(极少数可能性)?这很难说.你可以将它附加到我们现有的index2,你最终会得到一个可以在所有三个secnarios中使用的索引:
search_index (active, race_type, recordable_type, recordable_id, user_id)
Run Code Online (Sandbox Code Playgroud)
...或者它可能值得为此scanario提供第二个索引......
您的问题很特殊,因为您只=在where子句中使用.还有,如果你有这样的事情很多其他因素AND (race_type = 1 OR race_type=8)不提>或<.此外,如果您使用ORDER BY它,可以考虑您使用的索引.