本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。 Elasticsearch: 权威指南 » 数据建模 » 父-子关系文档 » 实际使用中的一些建议 « 祖辈与孙辈关系 扩容设计 »
实际使用中的一些建议编辑
当文档索引性能远比查询性能重要 的时候,父子关系是非常有用的,但是它也是有巨大代价的。其查询速度会比同等的嵌套查询慢5到10倍!
全局序号和延迟编辑
父子关系使用了全局序数 来加速文档间的联合。不管父子关系映射是否使用了内存缓存或基于硬盘的 doc values,当索引变更时,全局序数要重建。
一个分片中父文档越多,那么全局序数的重建就需要更多的时间。父子关系更适合于父文档少、子文档多的情况。
全局序数默认情况下是延迟构建的:在refresh后的第一个父子查询会触发全局序数的构建。而这个构建会导致用户使用时感受到明显的迟缓。你可以使用全局序数预加载 来将全局序数构建的开销由query阶段转移到refresh阶段,设置如下:
PUT /company { "mappings": { "branch": {}, "employee": { "_parent": { "type": "branch", "fielddata": { "loading": "eager_global_ordinals" } } } } }
|
在一个新的段可搜索前, |
当父文档过多时,全局序数的构建会耗费很多时间。此时可以通过增加 refresh_interval
来减少 refresh 的次数,延长全局序数的有效时间,这也很大程度上减小了全局序数每秒重建的cpu消耗。
多代使用和结语编辑
多代文档的联合查询(查看 祖辈与孙辈关系)虽然看起来很吸引人 ,但必须考虑如下的代价:
- 联合越多,性能越差。
-
每一代的父文档都要将其字符串类型的
_id
字段存储在内存中,这会占用大量内存。
当你考虑父子关系是否适合你现有关系模型时,请考虑下面这些建议 :
- 尽量少地使用父子关系,仅在子文档远多于父文档时使用。
- 避免在一个查询中使用多个父子联合语句。
- 在 has_child 查询中使用 filter 上下文,或者设置 score_mode 为 none 来避免计算文档得分。
- 保证父 IDs 尽量短,以便在 doc values 中更好地压缩,被临时载入时占用更少的内存。
最重要的是: 先考虑下我们之前讨论过的其他方式来达到父子关系的效果。
« 祖辈与孙辈关系 扩容设计 »Getting Started Videos
- Starting Elasticsearch
- Introduction to Kibana
- Logstash Starter Guide
官方地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/parent-child-performance.html