We've created a new Elasticsearch index (test-events-v4) with what we believed to be a more optimized mapping for storage. However, during load testing, we've observed significantly higher 99th percentile and max latency compared to the old index (test-events-old) — even when querying the exact same data set and using the same query logic.
Here’s an example query used on both indices:
GET /<index>/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"should": [
{
"bool": {
"filter": [
{ "term": { "status": <value> }},
{ "term": { "addressId": <value> }}
]
}
}
]
}
},
"sort": [
{
"timestamp": {
"order": "desc"
}
}
]
}
Key differences between new and old index:
Many of the fields like (status, addressId) was of type text
+ keyword
field, I have changed it to "keyword" field.
Also the fields which are not being searched or aggregated I have added this settings:
"index": false,
"doc_values": false
there were some object type fields I have stopped mapping the nested fields there, like before it was:
metadata: {
"type": {
// mapping
},
"created": { }
"mode": {}
}
I changed them now to this:
metadata: {
"type": "object",
"dynamic": "false"
}
I ran a benchmark after that, I got this result.
Index 99th Percentile Latency Max Latency
test-events-old ~640ms ~880ms
test-events-new ~1050ms ~6600ms
Although I see my new mapping has improved index creation time and store size, but query time is significantly higher. Although segments count is not much, segment sizes are uniform I have checked.
index docs.count docs.deleted store.size segments.count indexing.index_total indexing.index_time
test-events-new 15882 0 31.3mb 10 60000 6.1s
test-events-old 15881 0 42.9mb 12 90000 17.6s
Does "enabled": false
or "dynamic": "false"
on nested fields contribute to latency even if those fields aren’t used in the query? what should I do?