面试题答案
一键面试doc_values对查询性能的影响及优化
- 数字、日期、IP等字段
- 影响:doc_values是在索引构建时创建的一种列式存储结构,用于排序、聚合和脚本操作。对于数字、日期、IP等字段,开启doc_values能极大提升范围查询、排序和聚合操作的性能。例如,在按日期范围查询最近一周的数据并进行聚合统计时,如果日期字段开启了doc_values,ES可以快速从列式存储中读取相关数据进行计算,无需遍历整个倒排索引。
- 优化:在数字、日期、IP等需要频繁进行排序、聚合操作的字段上,应始终开启doc_values。如在定义映射时:
{
"mappings": {
"properties": {
"number_field": {
"type": "long",
"doc_values": true
},
"date_field": {
"type": "date",
"doc_values": true
},
"ip_field": {
"type": "ip",
"doc_values": true
}
}
}
}
- 文本字段
- 影响:对于文本字段,默认情况下ES不会为其开启doc_values,因为文本字段通常用于全文搜索,倒排索引更适合此类操作。但如果需要对文本字段进行排序或聚合(如按某个关键词的出现频率聚合),开启doc_values会占用额外的磁盘空间,并且构建索引的时间会增加。
- 优化:仅在确实需要对文本字段进行排序或聚合操作时,才开启doc_values。同时,可以考虑对文本进行多字段映射,一个字段用于全文搜索(不开启doc_values),另一个字段用于排序和聚合(开启doc_values)。例如:
{
"mappings": {
"properties": {
"text_field": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"doc_values": true
}
}
}
}
}
}
这里text_field
用于全文搜索,text_field.keyword
用于排序和聚合。
index对查询性能的影响及优化
- 精确匹配查询
- 影响:
index
属性决定字段是否被索引。对于精确匹配查询(如根据ID查询文档),只有当字段index
为true
时才能实现高效查询。如果设置为false
,该字段无法被搜索到。例如,在根据用户ID精确查找用户文档时,ID字段必须设置index: true
,ES会为其构建倒排索引,通过ID能快速定位到对应的文档。 - 优化:对于需要进行精确匹配查询的字段,如ID、订单号等,务必设置
index: true
。在映射定义中:
- 影响:
{
"mappings": {
"properties": {
"id_field": {
"type": "keyword",
"index": true
}
}
}
}
- 不需要搜索的字段
- 影响:如果某些字段仅用于存储数据,不需要参与任何查询(如一些内部使用的元数据字段),设置
index: false
可以减少索引大小,加快索引构建速度。因为ES无需为这些字段构建倒排索引。 - 优化:明确不需要搜索的字段,设置
index: false
。例如:
- 影响:如果某些字段仅用于存储数据,不需要参与任何查询(如一些内部使用的元数据字段),设置
{
"mappings": {
"properties": {
"internal_metadata": {
"type": "text",
"index": false
}
}
}
}
- 模糊查询
- 影响:对于模糊查询,字段
index
必须为true
。但不同的分析器设置会影响模糊查询的效果和性能。例如,使用标准分析器对文本进行分词后,模糊查询的范围和匹配程度会与自定义分析器不同。 - 优化:选择合适的分析器对于模糊查询性能至关重要。对于英文文本,可以使用
english
分析器,它能更好地处理英文单词的词干提取等操作,提高模糊查询的准确性和效率。在映射中设置:
- 影响:对于模糊查询,字段
{
"mappings": {
"properties": {
"text_for_fuzzy": {
"type": "text",
"index": true,
"analyzer": "english"
}
}
}
}
store对查询性能的影响及优化
- 基本影响
- 影响:
store
属性决定字段的值是否单独存储,与_source字段区分开来。如果设置store: true
,可以直接从存储中获取该字段的值,而无需从_source字段中解析。但这会占用额外的磁盘空间。对于一些大字段(如长文本),如果频繁需要单独获取该字段的值,设置store: true
可能会提升性能。然而,如果该字段很少单独被获取,开启store
只会增加存储负担。 - 优化:对于小字段或者经常和其他字段一起从_source中获取的字段,不建议设置
store: true
。对于大字段且频繁单独获取的场景,如单独获取文章内容字段,可以设置store: true
。例如:
- 影响:
{
"mappings": {
"properties": {
"article_content": {
"type": "text",
"store": true
}
}
}
}
- _source与store的权衡
- 影响:如果关闭了_source(通过设置
_source: false
),并且需要获取某个字段的值,就必须设置store: true
。但关闭_source会导致无法完整获取文档的原始内容,在一些需要返回完整文档的场景(如展示文档详情)会受限。 - 优化:除非有非常明确的空间限制和仅获取特定字段的需求,一般不建议关闭_source。在这种情况下,合理评估是否设置
store: true
,优先从_source中获取字段值,只有在性能确实受限时,再考虑对特定字段设置store: true
。
- 影响:如果关闭了_source(通过设置