# Why range filter in Elasticsearch takes much more CPU then full text search?

**URL:** <https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636>\
**Category:** Elasticsearch\
**Created:** [October 21, 2015, 5:52am UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636 "2015-10-21T05:52:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![un1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/un1t/32/5365_2.png) [@un1t](https://discuss.elastic.co/u/un1t)\
**Post date:** [October 21, 2015, 5:52am UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636/1 "2015-10-21T05:52:24Z")

</div>

I have a Filtred Query.

I first case I user full text search:

```
{ 'query': {'filtered': {'filter': {'bool': {'must': [{'term': {'status': 4}}]}},
                    'query': {'bool': {'should': [{'match': {'name': {'operator': 'and',
                                                                      'query': 'dog'}}},
                                                  {'match': {'description': {'boost': 0.9,
                                                                             'operator': 'and',
                                                                             'query': 'dog'}}},
                                                  {'match': {'author': {'boost': 0.8,
                                                                        'operator': 'and',
                                                                        'query': 'dog'}}},
                                                  {'match': {'tags': {'boost': 0.7,
                                                                      'operator': 'and',
                                                                      'query': 'dog'}}}]}}

```

In second case I use range filter:

```
{'query': {'filtered': {'filter': {'bool': {'must': [{'term': {'status': 4}},
                                                 {'range': {'year_to': {'lte': '1946'}}}]}}}}

```

I was very surprised, because second request takes 2 times more CPU than the first one;

What is going on?

My mapping:

```
"properties": {
"id": {
    "type": "integer"
},
"name": {
    "analyzer": "russian_morphology",
    "type": "string"
},
"description": {
    "analyzer": "russian_morphology",
    "type": "string"
},
"status": {
    "type": "integer"
},
"tags": {
    "analyzer": "russian_morphology",
    "type": "string"
},
"year_from": {
    "type": "integer"
},
"year_to": {
    "type": "integer"
}
```

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [October 21, 2015, 12:45pm UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636/2 "2015-10-21T12:45:20Z")

</div>

> [@un1t](#):
>
> I was very surprised, because second request takes 2 times more CPU than the first one;
> 
> What is going on?

The first query is ultimately translated into a boolean combination of 5 term queries which can use the terms dictionary to jump directly to the documents that they need. The term queries are fast and the bool queries are fast.

The second query is ultimately translated into a term query (fast again) and a numeric range query. The numeric range query has to walk the terms dictionary to find its matches. Part of the work that it does is proportional to the number of distinct values less than or equal to 1946. I don't know if that is the term that dominates the runtime - it could be that there are lots of hits lte 1946. You could certainly try and take stack traces to figure out what exactly is up here - just spam the query with ab and then use jstack and look for stuff like `TermRangeFilter` (or `TermRangeQuery` post 2.0). But if you are just looking for an intuitive explanation of why complex looking queries are can be faster - what I wrote above might be good enough.

---

<div class="post-metadata">

**Author:** ![un1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/un1t/32/5365_2.png) [@un1t](https://discuss.elastic.co/u/un1t)\
**Post date:** [October 21, 2015, 1:57pm UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636/3 "2015-10-21T13:57:21Z")

</div>

Thanks for reply.

So seems {'range':{'lte':1946}} transforms into terms filters with about 80 values.

It is possible to rewrite second query to make it faster? I did try "numeric\_range" filter, but perfomance seems the same.

---

<div class="post-metadata">

**Author:** ![nik9000](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nik9000/32/44947_2.png) [@nik9000](https://discuss.elastic.co/u/nik9000)\
**Post date:** [October 21, 2015, 2:16pm UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636/4 "2015-10-21T14:16:13Z")

</div>

> [@un1t](#):
>
> So seems {'range':{'lte':1946}} transforms into terms filters with about 80 values.

I suppose it depends on your mapping - numeric\_range should automatically kick in for numbers. There is a precision\_step you can play with but I don't know much about it. What kind of performance are you seeing - like how long is the query taking and how many documents is it hitting? Beyond that I'm not sure I can be much help. Usually this is where I'd break out `ab` and `jstack` to figure out what is going on.

---

<div class="post-metadata">

**Author:** ![un1t](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/un1t/32/5365_2.png) [@un1t](https://discuss.elastic.co/u/un1t)\
**Post date:** [October 21, 2015, 2:55pm UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636/5 "2015-10-21T14:55:13Z")

</div>

mapping for this field is integer.  
Query takes 20 ms.  
I have 60k documents in index. And I have 20 documents in response. Response "total" attribute 35k. Unfortunately I don't know much about java and jstack.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 11:43pm UTC](https://discuss.elastic.co/t/why-range-filter-in-elasticsearch-takes-much-more-cpu-then-full-text-search/32636/6 "2017-07-05T23:43:31Z")

</div>


