New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OR'ed optimization in 3.0 is ineffective if WHERE-clause contains two expressions [CORE4537] #4855
Comments
Modified by: @pavel-zotovdescription: DDL: create or alter procedure null_arg_force_idx_usage as begin end; set term ^; commit; set term ^; create or alter procedure null_arg_force_idx_usage( create or alter procedure null_arg_optimization_test_01( create or alter procedure null_arg_optimization_test_02( So, the table tmp(id int, doc_id int, qty int) contains 10^6 rows and we have three procedures which all take two arguments (both nullable) and returns first record from TMP which match to one and/or two values of input args (or returns first record if no arguments passed). Procedure `null_arg_force_idx_usage` does not use so called "OR'ed optimization" - it only forces FB to use indexes via BETWEEN + pair of literals which covers all possible values of input args. It is provided here only for comparison. Procedures `null_arg_optimization_test_01` and `null_arg_optimization_test_02` differs only in the order of expressions in WHERE-clause. The following samples shows statistics of these SPs. 1.1 select * from null_arg_force_idx_usage(null, null) ==> IR = 1, NIR = 0; 174 ms, 1331 fetch(es) 2.1 select * from null_arg_force_idx_usage(1) ==> IR = 1, NIR = 0; 23 ms, 738 fetch(es) 3.1 select * from null_arg_force_idx_usage(-1); ==> no statistics, 21 ms, 730 fetch(es) 4.1 select * from null_arg_force_idx_usage(null,1); ==> IR=1; 14 ms, 607 fetch(es) 5.1 select * from null_arg_force_idx_usage(null,-1); ==> no statistics; 0 ms, 3 fetch(es) => DDL: create or alter procedure null_arg_force_idx_usage as begin end; set term ^; commit; set term ^; create or alter procedure null_arg_force_idx_usage( create or alter procedure null_arg_optimization_test_01( create or alter procedure null_arg_optimization_test_02( So, the table tmp(id int, doc_id int, qty int) contains 10^6 rows and we have three procedures which all take two arguments (both nullable) and returns first record from TMP which match to one and/or two values of input args (or returns first record if no arguments passed). Procedure `null_arg_force_idx_usage` does not use so called "OR'ed optimization" - it only forces FB to use indexes via BETWEEN + pair of literals which covers all possible values of input args. It is provided here only for comparison. Procedures `null_arg_optimization_test_01` and `null_arg_optimization_test_02` differs only in the order of expressions in WHERE-clause. The following samples shows statistics of these SPs. 1.1 select * from null_arg_force_idx_usage(null, null) ==> IR = 1, NIR = 0; 174 ms, 1331 fetch(es) 2.1 select * from null_arg_force_idx_usage(1) ==> IR = 1, NIR = 0; 23 ms, 738 fetch(es) 3.1 select * from null_arg_force_idx_usage(-1); ==> no statistics, 21 ms, 730 fetch(es) 4.1 select * from null_arg_force_idx_usage(null,1); ==> IR=1; 14 ms, 607 fetch(es) 5.1 select * from null_arg_force_idx_usage(null,-1); ==> no statistics; 0 ms, 3 fetch(es) |
Modified by: @pavel-zotovsummary: OR'ed optimization in 3.0 is ineffective when `WHERE` clause contains two expression and they do NOT match order of SP input arguments => OR'ed optimization in 3.0 is ineffective if WHERE-clause contains two expression and they do NOT match to order of SP input arguments |
Modified by: @dyemanovassignee: Dmitry Yemanov [ dimitr ] |
Modified by: @dyemanovRegression: 3.0 Alpha 2 [ 10560 ] |
Commented by: @dyemanov I've corrected the ticket title as it has nothing to do with order of SP parameters, only order of predicates inside WHERE matters here. The issue is that if two ORed predicates are ANDed, then only the first one can possibly use indices. As simple as that. So if SP test_01 is called with a_doc_list_id = null, then a fullscan happens, otherwise only index on DOC_ID is used. If SP test_02 is called with a_doc_data_id = null, then a fullscan happens, otherwise only index on ID is used. |
Modified by: @dyemanovComponent: Engine [ 10000 ] summary: OR'ed optimization in 3.0 is ineffective if WHERE-clause contains two expression and they do NOT match to order of SP input arguments => OR'ed optimization in 3.0 is ineffective if WHERE-clause contains two expressions |
Modified by: @dyemanovFix Version: 3.0.0 [ 10048 ] |
Modified by: @dyemanovFix Version: 3.0 RC2 [ 10048 ] => |
Submitted by: @pavel-zotov
DDL:
So, the table
tmp(id int, doc_id int, qty int)
contains 10^6 rows and we have three procedures which all take two arguments (both nullable) and returns first record from TMP which match to one and/or two values of input args (or returns first record if no arguments passed).Procedure
null_arg_force_idx_usage
does not use so called "OR'ed optimization" -- it only forces FB to use indexes via BETWEEN + pair of literals which covers all possible values of input args. It is provided here only for comparison.Procedures
null_arg_optimization_test_01
andnull_arg_optimization_test_02
differs only in the order of expressions in WHERE-clause.The following samples shows statistics of these SPs.
The text was updated successfully, but these errors were encountered: