Оптимизация запроса с несколькими aggs


#1

Есть запрос вида:

{
    "aggs": {
        "test": {
            "date_histogram": {
                "field": "user.date",
                "interval": "1d"
            },
            "aggs": {
                "all_view": {
                    "sum": {
                        "field": "view"
                    }
                },
                "uniq_users": {
                    "cardinality": {
                        "field": "uid"
                    }
                }

            }
        }
    }
}

где во втором aggs может быть до 10-15 однотипных полей с sum. В принципе этот вопрос работает ( 30-50 секунд на 150 Гб ). Возможно ли оптимизировать этот запрос ( например разделить на 10-15 маленьких запросов по каждому sum отдельно или может быть какой индекс добавить ? ) Текущий mapping для индекса:

{
 "template" : "test",
 "mappings" : {
    "_default_" : {
       "_all" : {"enabled" : true},
       "dynamic_templates" : [ {
         "string_fields" : {
           "match" : "*",
           "match_mapping_type" : "string",
           "mapping" : {
             "type" : "multi_field",
               "fields" : {
                 "{name}" : {"type": "string", "index" : "analyzed", "omit_norms" : true, analyzer: "keyword" }
               }
           }
         }
       } ],
       "properties" : {
         "@version": { "type": "string", "index": "not_analyzed" }
       }
    }
  }
}

(Igor Motov) #2

То есть эта часть повторяется 10-15 раз с разными полями?

                "all_view": {
                    "sum": {
                        "field": "view"
                    }
                },
                "some_view": {
                    "sum": {
                        "field": "view1"
                    }
                },
                "some_other_view": {
                    "sum": {
                        "field": "view2"
                    }
                },
               ....... и т.д. 10-15 раз .....

#3

да с разными полями


(Igor Motov) #4

Когда в запросе присутствуют несколько агрегаций, этот запрос обрабатывается следующим образом: сначала запрос разбивается на несколько подзапросов для каждой шарды, и все подзапросы начинают выполняться параллельно (если, конечно, в пуле потоков есть свободные потоки). Каждые подзапрос начинает поиск и потом выполняет каждую агрегацию последовательно на каждой записи, возвращенной поиском. И это последовательное исполнение может быть причиной долгой работы запроса. Поэтому такой запрос иногда можно ускорить увеличением количества шард в индексе либо разделением запроса на 2 или более отдельных запросов. Однако, увеличение степени параллелизации будет работать до тех пор, пока есть свободные циклы ЦПУ и I/O не перенасыщен. После этого надо будет смотреть каким образом можно уменьшить нагрузку, а это зависит от версии elasticsearch и от того какого ресурса не хватает. Последнее можно определить запуском hot_threads во время исполнения запроса.


(system) #5