【发布时间】:2021-09-14 16:25:34
【问题描述】:
我有一张大桌子,上面有关于他们的外表和技能的信息,比如年龄、眼睛颜色、发型、弹钢琴等
所有这些字段都是可搜索的,因此用户可以搜索弹吉他并拥有蓝眼睛的人。
在这种特殊情况下如何处理索引?我知道我不能为所有列创建索引,因为它会影响写入时间。那么这种场景的最佳方法是什么?
【问题讨论】:
-
示例数据以及查询示例会有所帮助。
我有一张大桌子,上面有关于他们的外表和技能的信息,比如年龄、眼睛颜色、发型、弹钢琴等
所有这些字段都是可搜索的,因此用户可以搜索弹吉他并拥有蓝眼睛的人。
在这种特殊情况下如何处理索引?我知道我不能为所有列创建索引,因为它会影响写入时间。那么这种场景的最佳方法是什么?
【问题讨论】:
创建索引始终是一种权衡。您自己做出了部分权衡:由于写入速度的原因,您不能为每一列创建索引。您可以创建多少索引取决于您在读取加速和写入减速之间的权衡。这由您决定:如果您每晚在办公时间以外更新表格并且只在白天阅读,那么权衡与持续更新时的权衡是不同的。
如果您的权衡表明您只能创建 2 个索引,那么您可能希望在它们影响最大的地方创建它们。那些是哪些列?我们显然不知道,但您可能会得到一些提示:
这些是需要考虑的几点。由于您的问题很笼统,我的回答也必然如此。
【讨论】:
您无法以最佳方式索引所有可能的组合。例如,如果要搜索plays_guitar=true 和eye_color='blue',则需要在(plays_guitar, eye_color) 列对上使用复合索引。如果两个条件相等,则索引中列的顺序没有太大区别,但使用复合索引确实有很大帮助。
问题在于,这意味着您不仅需要为每一列创建一个索引,还需要所有可能的组合。所以 n 列有 2n 个索引。
但也需要考虑不平等条件。例如,如果要搜索plays_guitar=true 和eye_color <> 'blue',则后一个条件是不等式。那么索引中列的顺序确实很重要。您可以将多个列用于相等条件,首先在索引中。然后,您可以将用于不等式条件的 一个 列放在其他列之后。
因此,您不仅需要 2n 个索引,还需要列的所有 排列 的索引(即组合但重要的排序),它的顺序是 n!索引。鉴于数据库的实际限制,显然这是不可能的。
唯一的选择是索引 一些 可搜索的列,并希望充分缩小搜索范围。将逐行评估不在索引中的其他列的条件。这是您在查询执行中获得大量“检查行”的地方。
这不如仅通过索引查找来查找行,但可能不会破坏交易。
因此,由您来设计一组有限的索引,这些索引将“足够好”以缩小最可能的搜索范围。
欢迎成为一名专业的软件工程师——您需要运用自己的判断力和经验,而且您无法优化所有可能的结果。
如果您被告知搜索是完全不可预测的,并且所有可能的搜索都应该被视为同等可能,那么这不是可以解决的方案,至少不能使用 B-Tree 索引。
然后您可以尝试将数据调整为全文搜索架构,您可以在其中索引整个数据集并搜索任意列组合中的值。
目前此类数据库最流行的示例是 Elasticsearch,它基于开源 Apache Lucene 搜索引擎。
如果您想坚持开源产品(最新版本的 Elasticsearch 不再开源),Apache Solr 是另一个不错的选择。
【讨论】: