面试题答案
一键面试使用from和size分页的局限性
- 性能问题:随着
from
值的增大,查询性能会急剧下降。因为 Elasticsearch 需要从索引的起始位置开始扫描from + size
条数据,然后再丢弃前from
条数据,只返回后面size
条数据,这会消耗大量的资源和时间。 - 深度分页问题:
from
的取值有一定限制,一般在 Elasticsearch 中,from + size
的总和不能超过index.max_result_window
(默认值为 10000),如果超过这个值,查询会失败。
优化分页方式
- 使用 scroll 滚动查询:
- 原理:
scroll
会在首次查询时创建一个快照,后续的查询基于这个快照进行,它会返回一个scroll_id
,通过这个scroll_id
可以不断获取下一页的数据。 - 示例:
- 原理:
POST /your_index/_search?scroll=1m
{
"size": 100,
"query": {
"match_all": {}
}
}
首次查询会返回数据和 scroll_id
,之后使用 scroll_id
继续查询:
POST /_search/scroll
{
"scroll": "1m",
"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
- 注意:
scroll
主要用于批量处理大量数据,不适用于实时用户请求,因为它创建的快照不会反映查询期间索引的变化。
- 使用 search_after 分页:
- 原理:
search_after
基于上一页的最后一条数据的排序值进行分页,它不需要像from + size
那样从索引起始位置开始扫描。 - 示例:假设按
timestamp
字段降序排序分页:
- 原理:
POST /your_index/_search
{
"size": 10,
"query": {
"match_all": {}
},
"sort": [
{
"timestamp": {
"order": "desc"
}
}
]
}
返回结果中的最后一条数据包含 sort
字段的值,使用这个值进行下一页查询:
POST /your_index/_search
{
"size": 10,
"query": {
"match_all": {}
},
"search_after": [1577836800000],
"sort": [
{
"timestamp": {
"order": "desc"
}
}
]
}
- 优点:适用于实时请求,并且不受
index.max_result_window
的限制,性能相对较好。