Kouhei Sutou
null+****@clear*****
Wed May 16 11:59:01 JST 2018
Kouhei Sutou 2018-05-16 11:59:01 +0900 (Wed, 16 May 2018) New Revision: 69fda634fa875090529a9794680ad8cc655654b6 https://github.com/groonga/groonga/commit/69fda634fa875090529a9794680ad8cc655654b6 Message: grn_table_select: optimize a case that needs any temporary table If op is GRN_OP_AND and res has any records, temporary tables are initialized with the records int the res. It will reduce search cost. It will optimize "||" conditions in sub_filter() case. For example, 13s -> 0.2s. Added files: test/command/suite/select/function/sub_filter/column/scalar/filtered_or.expected test/command/suite/select/function/sub_filter/column/scalar/filtered_or.test Modified files: lib/expr.c Modified: lib/expr.c (+34 -0) =================================================================== --- lib/expr.c 2018-05-16 11:24:13 +0900 (f38285467) +++ lib/expr.c 2018-05-16 11:59:01 +0900 (30c6be156) @@ -7177,10 +7177,34 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr, uint32_t codes_curr = e->codes_curr; grn_id min_id = GRN_ID_NIL; grn_obj condition_inspect_buffer; + grn_obj *base_res = NULL; v = grn_expr_get_var_by_offset(ctx, (grn_obj *)e, 0); GRN_PTR_INIT(&res_stack, GRN_OBJ_VECTOR, GRN_ID_NIL); GRN_TEXT_INIT(&condition_inspect_buffer, 0); + + if (res_size > 0 && op == GRN_OP_AND) { + grn_bool have_push = GRN_FALSE; + for (i = 0; i < scanner->n_sis; i++) { + scan_info *si = scanner->sis[i]; + if (si->flags & SCAN_PUSH) { + have_push = GRN_TRUE; + break; + } + } + if (have_push) { + base_res = grn_table_create(ctx, + NULL, 0, + NULL, + GRN_OBJ_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, + table, + NULL); + if (base_res) { + grn_table_setoperation(ctx, base_res, res, base_res, GRN_OP_OR); + } + } + } + for (i = 0; i < scanner->n_sis; i++) { scan_info *si = scanner->sis[i]; if (si->flags & SCAN_POP) { @@ -7200,6 +7224,13 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr, if (!res_) { break; } + if (base_res && si->logical_op == GRN_OP_OR) { + GRN_LOG(ctx, GRN_REPORT_INDEX_LOG_LEVEL, + "[table][select][push][initial] <%u>", + grn_table_size(ctx, base_res)); + grn_table_setoperation(ctx, res_, base_res, res_, GRN_OP_OR); + si->logical_op = GRN_OP_AND; + } GRN_PTR_PUT(ctx, &res_stack, res); res = res_; min_id = GRN_ID_NIL; @@ -7237,6 +7268,9 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr, } GRN_OBJ_FIN(ctx, &condition_inspect_buffer); + if (base_res) { + grn_obj_close(ctx, base_res); + } i = 0; if (!res_created) { i++; } Added: test/command/suite/select/function/sub_filter/column/scalar/filtered_or.expected (+42 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/sub_filter/column/scalar/filtered_or.expected 2018-05-16 11:59:01 +0900 (1be8e943d) @@ -0,0 +1,42 @@ +table_create Files TABLE_PAT_KEY ShortText +[[0,0.0,0.0],true] +column_create Files revision COLUMN_SCALAR UInt32 +[[0,0.0,0.0],true] +table_create Packages TABLE_PAT_KEY ShortText +[[0,0.0,0.0],true] +column_create Packages file COLUMN_SCALAR Files +[[0,0.0,0.0],true] +column_create Files packages_files_index COLUMN_INDEX Packages file +[[0,0.0,0.0],true] +table_create Revisions TABLE_PAT_KEY UInt32 +[[0,0.0,0.0],true] +column_create Revisions files_revision COLUMN_INDEX Files revision +[[0,0.0,0.0],true] +load --table Files +[ +{"_key": "include/groonga.h", "revision": 30}, +{"_key": "lib/groonga.rb", "revision": 12}, +{"_key": "ha_mroonga.cc", "revision": 40} +] +[[0,0.0,0.0],3] +load --table Packages +[ +{"_key": "groonga", "file": "include/groonga.h"}, +{"_key": "rroonga", "file": "lib/groonga.rb"}, +{"_key": "mroonga", "file": "ha_mroonga.cc"} +] +[[0,0.0,0.0],3] +log_level --level info +[[0,0.0,0.0],true] +select Packages --filter '_key == "rroonga" && sub_filter(file, "(revision <= 20 || revision > 30) && (_id > 0 || _id < 10)")' --output_columns '_key, files, files.revision' +[[0,0.0,0.0],[[[1],[["_key","ShortText"]],["rroonga"]]]] +#|i| [table][select][index][equal][accessor][key] <Packages> +#|i| [table][select][index][selector][no-index][sub_filter] <Packages> +#|i| [sub_filter][pre-filter][column][scalar] <Packages.file> -> <Files> +#|i| [table][select][push][initial] <1> +#|i| [table][select][index][range] <Revisions.files_revision> +#|i| [table][select][index][range] <Revisions.files_revision> +#|i| [table][select][push][initial] <1> +#|i| [accessor][resolve][data-column][index] <Files.packages_files_index> +log_level --level notice +[[0,0.0,0.0],true] Added: test/command/suite/select/function/sub_filter/column/scalar/filtered_or.test (+33 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/function/sub_filter/column/scalar/filtered_or.test 2018-05-16 11:59:01 +0900 (275a7bae1) @@ -0,0 +1,33 @@ +table_create Files TABLE_PAT_KEY ShortText +column_create Files revision COLUMN_SCALAR UInt32 + +table_create Packages TABLE_PAT_KEY ShortText +column_create Packages file COLUMN_SCALAR Files + +column_create Files packages_files_index COLUMN_INDEX Packages file + +table_create Revisions TABLE_PAT_KEY UInt32 +column_create Revisions files_revision COLUMN_INDEX Files revision + +load --table Files +[ +{"_key": "include/groonga.h", "revision": 30}, +{"_key": "lib/groonga.rb", "revision": 12}, +{"_key": "ha_mroonga.cc", "revision": 40} +] + +load --table Packages +[ +{"_key": "groonga", "file": "include/groonga.h"}, +{"_key": "rroonga", "file": "lib/groonga.rb"}, +{"_key": "mroonga", "file": "ha_mroonga.cc"} +] + +#@add-important-log-levels info +log_level --level info +select Packages \ + --filter '_key == "rroonga" && \ + sub_filter(file, "(revision <= 20 || revision > 30) && (_id > 0 || _id < 10)")' \ + --output_columns '_key, files, files.revision' +log_level --level notice +#@remove-important-log-levels info -------------- next part -------------- HTML����������������������������... URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180516/55a9e958/attachment-0001.htm