天天看點

ES優化實戰-通過開啟copy_to提升一倍的檢索性能

  在對text字段進行搜尋的時候,假如你需要對多個text類型的字段搜尋,例如 文章的标題和文章的内容,這兩個字段。

  在這種情況下,是可以開啟copy_to來提速的。我測試的提速效果在百分之五十左右。

  它是将這兩個字段copy到一個字段上,然後進行分詞處理。之是以會快,就是因為如果你多個字段,要做多次的查詢,如果合并到一個字段上,隻需要做一次查詢。

  但是請注意,它會額外花費比較多的磁盤資源!

測試結論

對兩個text類型字段檢索,資料内容為文章和标題。開啟copy_to以後,搜尋提升百分之五十左右。磁盤額外占用百分之二十五左右。

如何開啟copy_to

我這裡不做過多的介紹了,直接看官網吧。

​​copy_to | Elasticsearch Guide [8.4] | Elastic​​

看看資源花費情況

 GET _cat/indices?v

可以看到索引在開啟copy_to前是583G,開啟後是724G。磁盤多花費了24%。這個要根據自己資料情況,具體去測試分析。因為大家的資料,場景都不一樣。

ES優化實戰-通過開啟copy_to提升一倍的檢索性能

 看看提升效果

  我是寫測試程式跑了幾百個搜尋詞條件,做測試。搜尋就是query_string,然後mache_phrase

  測試代碼如下: 

@Override
    public void comparisonCopyTo() throws IOException {
        // 搜尋詞
        List<String> queryList = Arrays.asList("中國", "美國", "疫情", "蘋果", "華為",  "利好", "浪漫", "馬斯特",
                "特斯拉", "台灣", "香港", "美食", "微信", "晴天", "北京", "救援", "失敗", "報警",
                "媒體", "新疆", "京東", "深圳", "爆炸", "事故", "征地", "抗議", "聚衆",
                "堵路", "打砸", "罷工", "跳樓", "招募", "黑旅館", "争議", "盜竊", "碰車", 
                "不滿", "黑中介", "失火", "舉報", "公道", "經濟學家", "中國新聞周刊", "永定河", "中國大地财産保險股份有限公司", "冬奧",
                "天津大事件");


        // 對比邏輯:相同的搜尋詞,去對比搜尋時間,列印日志,校驗搜尋結果
        for (String queryString:queryList) {

            HashMap<String, Float> fields = new HashMap<>();
            fields.put("content", 1.0F);
            fields.put("title", 1.0F);
            QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(queryString).fields(fields).type(MultiMatchQueryBuilder.Type.PHRASE);
            SearchResponse data = commonsDao.basicSearch(queryBuilder, 10, true, "all_data");

            // 查詢copy-to的字段
            HashMap<String, Float> copyToFields = new HashMap<>();
            copyToFields.put("full_search", 1.0F);
            QueryStringQueryBuilder copyToQueryBuilder = QueryBuilders.queryStringQuery(queryString).fields(copyToFields).type(MultiMatchQueryBuilder.Type.PHRASE);
            SearchResponse copyToData = commonsDao.basicSearch(copyToQueryBuilder, 10, true, "all_data_copy_to");

            log.info("copy-to測試對比(un copy-to vs copy-to), 搜尋詞 {},查詢時間對比 {} vs {}, 查詢性能提升 {}% ,查詢結果對比 {} vs {}", queryString,
                    data.getTook().getMillis(), copyToData.getTook().getMillis(), (float)(data.getTook().getMillis() - copyToData.getTook().getMillis())/data.getTook().getMillis()*100,
                    data.getHits().getTotalHits().value, copyToData.getHits().getTotalHits().value);
        }
    }