diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index e004bab3068..4c293669c68 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -1227,6 +1227,7 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { "rows_after_filter": 100, "rows_out": 1, "cost": 0.9604227, + "cost_without_join_buffer": 2.56761, "index_only": false, "chosen": false } @@ -1281,6 +1282,7 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b { "rows_after_filter": 100, "rows_out": 1, "cost": 0.9604227, + "cost_without_join_buffer": 2.56761, "index_only": false, "chosen": false } @@ -3455,6 +3457,7 @@ explain extended select * from t1 where a in (select p from t2) { "rows_after_filter": 101, "rows_out": 101, "cost": 0.063593833, + "cost_without_join_buffer": 0.10333002, "index_only": false, "chosen": true } @@ -5206,6 +5209,7 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -5349,6 +5353,7 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -5375,6 +5380,7 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -5413,6 +5419,7 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_ "rows_after_filter": 3, "rows_out": 3, "cost": 0.015203373, + "cost_without_join_buffer": 0.094543335, "index_only": false, "chosen": true } @@ -5977,6 +5984,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -6003,6 +6011,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -6029,6 +6038,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -6055,6 +6065,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -6081,6 +6092,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -6119,6 +6131,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.050443503, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -6145,6 +6158,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.024600489, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -6171,6 +6185,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.024600489, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -6197,6 +6212,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.050443503, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -6235,6 +6251,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -6261,6 +6278,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.067582275, + "cost_without_join_buffer": 0.850890015, "index_only": false, "chosen": true } @@ -6287,6 +6305,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -6348,6 +6367,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.034460781, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -6374,6 +6394,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.080024379, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -6412,6 +6433,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -6492,6 +6514,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -6518,6 +6541,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -6556,6 +6580,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 6.764540577, + "cost_without_join_buffer": 25.02637682, "index_only": false, "chosen": true } @@ -6675,6 +6700,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.024443331, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -6701,6 +6727,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.024443331, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -6727,6 +6754,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.015203373, + "cost_without_join_buffer": 0.094543335, "index_only": false, "chosen": true } @@ -6753,6 +6781,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.024443331, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -6791,6 +6820,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -6817,6 +6847,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.067582275, + "cost_without_join_buffer": 0.850890015, "index_only": false, "chosen": true } @@ -6843,6 +6874,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -6899,6 +6931,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.034460781, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -6925,6 +6958,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.080024379, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -6963,6 +6997,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -7043,6 +7078,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -7069,6 +7105,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -7107,6 +7144,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 6.764540577, + "cost_without_join_buffer": 25.02637682, "index_only": false, "chosen": true } @@ -7218,6 +7256,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.017419989, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -7244,6 +7283,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.012618795, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -7270,6 +7310,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.017419989, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -7308,6 +7349,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.034460781, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -7334,6 +7376,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.080024379, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -7372,6 +7415,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -7452,6 +7496,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.034303623, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -7478,6 +7523,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.034303623, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -7516,6 +7562,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -7601,6 +7648,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.065233941, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -7627,6 +7675,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.065233941, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -7653,6 +7702,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.065233941, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -7691,6 +7741,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -7717,6 +7768,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -8233,6 +8285,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -8346,6 +8399,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -8567,6 +8621,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -8593,6 +8648,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -8619,6 +8675,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -8645,6 +8702,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.011523207, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -8671,6 +8729,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.014133225, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -8709,6 +8768,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.050443503, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -8735,6 +8795,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.024600489, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -8761,6 +8822,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.024600489, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -8787,6 +8849,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.050443503, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -8825,6 +8888,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -8851,6 +8915,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.067582275, + "cost_without_join_buffer": 0.850890015, "index_only": false, "chosen": true } @@ -8877,6 +8942,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -8943,6 +9009,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.034460781, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -8969,6 +9036,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.080024379, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -9007,6 +9075,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -9140,6 +9209,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.024443331, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -9166,6 +9236,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.024443331, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -9192,6 +9263,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.015203373, + "cost_without_join_buffer": 0.094543335, "index_only": false, "chosen": true } @@ -9218,6 +9290,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.024443331, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -9256,6 +9329,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -9282,6 +9356,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.067582275, + "cost_without_join_buffer": 0.850890015, "index_only": false, "chosen": true } @@ -9308,6 +9383,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.172815333, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -9374,6 +9450,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -9400,6 +9477,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -9460,6 +9538,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -9570,6 +9649,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.017419989, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -9596,6 +9676,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.012618795, + "cost_without_join_buffer": 0.031514445, "index_only": false, "chosen": true } @@ -9622,6 +9703,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.017419989, + "cost_without_join_buffer": 0.034329735, "index_only": false, "chosen": true } @@ -9660,6 +9742,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 3, "rows_out": 3, "cost": 0.034460781, + "cost_without_join_buffer": 0.283630005, "index_only": false, "chosen": true } @@ -9686,6 +9769,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.080024379, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -9724,6 +9808,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -9811,6 +9896,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.034303623, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -9837,6 +9923,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.034303623, + "cost_without_join_buffer": 0.102989205, "index_only": false, "chosen": true } @@ -9875,6 +9962,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.261557961, + "cost_without_join_buffer": 0.926902845, "index_only": false, "chosen": true } @@ -9963,6 +10051,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.065233941, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -9989,6 +10078,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.065233941, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -10015,6 +10105,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.065233941, + "cost_without_join_buffer": 0.308967615, "index_only": false, "chosen": true } @@ -10053,6 +10144,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -10079,6 +10171,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) { "rows_after_filter": 9, "rows_out": 9, "cost": 0.628673451, + "cost_without_join_buffer": 2.780708535, "index_only": false, "chosen": true } @@ -10917,7 +11010,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "rows": 1000, "rows_after_filter": 800, "rows_out": 800, - "cost": 0.834607, + "cost": 0.8329686, "index_only": false, "chosen": true } @@ -10927,7 +11020,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "type": "scan", "rows_read": 800, "rows_out": 800, - "cost": 0.834607, + "cost": 0.8329686, "uses_join_buffering": false } } @@ -10938,7 +11031,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "plan_prefix": "A", "table": "B", "rows_for_plan": 4000, - "cost_for_plan": 0.84620665 + "cost_for_plan": 0.84456825 } ] }, @@ -11366,6 +11459,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "rows_after_filter": 10, "rows_out": 1, "cost": 0.11055225, + "cost_without_join_buffer": 1.159965, "index_only": false, "chosen": true } @@ -11752,6 +11846,7 @@ UPDATE t, v SET t.b = t.a, t.a = v.c WHERE v.c < t.a { "rows_after_filter": 2, "rows_out": 2, "cost": 0.012911897, + "cost_without_join_buffer": 0.024837402, "index_only": false, "chosen": true } @@ -12713,7 +12808,7 @@ explain select * from t1 where a<10 and b between 10 and 50 and c < 10 { "rows": 9, "rows_after_filter": 0.189, "rows_out": 0.017766, - "cost": 0.005814057, + "cost": 0.006364199, "chosen": true } ], @@ -12721,7 +12816,7 @@ explain select * from t1 where a<10 and b between 10 and 50 and c < 10 { "type": "range", "rows_read": 0.189, "rows_out": 0.017766, - "cost": 0.005814057, + "cost": 0.006364199, "uses_join_buffering": false, "rowid_filter_index": "b" } @@ -12733,7 +12828,7 @@ explain select * from t1 where a<10 and b between 10 and 50 and c < 10 { "plan_prefix": "", "table": "t1", "rows_for_plan": 0.017766, - "cost_for_plan": 0.005814057, + "cost_for_plan": 0.006364199, "pushdown_cond_selectivity": 0.094, "filtered": 0.1974, "rows_out": 0.017766 @@ -12743,7 +12838,7 @@ explain select * from t1 where a<10 and b between 10 and 50 and c < 10 { { "best_join_order": ["t1"], "rows": 0.017766, - "cost": 0.005814057 + "cost": 0.006364199 }, { "table": "t1", @@ -13172,6 +13267,7 @@ explain format=json select * from three, t1 where t1.a=three.a and t1.b<5000 and "rows_after_filter": 430.7688, "rows_out": 323.0766, "cost": 1.701731924, + "cost_without_join_buffer": 4.7319164, "index_only": false, "chosen": true } diff --git a/mysql-test/main/optimizer_crash.result b/mysql-test/main/optimizer_crash.result index 2a9e8dd51ed..643a16c0e33 100644 --- a/mysql-test/main/optimizer_crash.result +++ b/mysql-test/main/optimizer_crash.result @@ -36,3 +36,24 @@ Warnings: Warning 1931 Query execution was interrupted. The query examined at least ### rows, which exceeds LIMIT ROWS EXAMINED (1000). The query result may be incomplete DROP VIEW v; DROP TABLE t1, t2, t3, t4, t5, t1000, t2000; +# +# MDEV-31391 Assertion `((best.records_out) == 0.0 && +# (best.records) == 0.0) || +# (best.records_out)/(best.records) < 1.0000001' failed +# +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY(a), KEY(b)) ENGINE=Aria; +INSERT INTO t1 VALUES +(1,13),(2,22),(3,8),(4,88),(5,6),(7,21),(9,64),(10,14),(11,15),(12,8), +(6,20),(8,39),(13,0),(14,3),(15,54),(16,85),(17,1),(18,1),(19,0),(20,0); +CREATE TABLE t2 (c INT) ENGINE=Aria; +INSERT INTO t2 VALUES (1),(2),(3); +EXPLAIN SELECT a FROM t1 JOIN t2 WHERE a = b AND c <> 7 GROUP BY a HAVING a != 6 AND a <= 9; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,b PRIMARY 4 NULL 9 Using index condition; Using where; Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +SELECT a FROM t1 JOIN t2 WHERE a = b AND c <> 7 GROUP BY a HAVING a != 6 AND a <= 9; +a +DROP TABLE t1, t2; +# +# End of 11.0 tests +# diff --git a/mysql-test/main/optimizer_crash.test b/mysql-test/main/optimizer_crash.test index d7aee294353..1134e4b6445 100644 --- a/mysql-test/main/optimizer_crash.test +++ b/mysql-test/main/optimizer_crash.test @@ -46,3 +46,23 @@ SELECT * FROM information_schema.TABLES # Cleanup DROP VIEW v; DROP TABLE t1, t2, t3, t4, t5, t1000, t2000; + +--echo # +--echo # MDEV-31391 Assertion `((best.records_out) == 0.0 && +--echo # (best.records) == 0.0) || +--echo # (best.records_out)/(best.records) < 1.0000001' failed +--echo # + +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY(a), KEY(b)) ENGINE=Aria; +INSERT INTO t1 VALUES +(1,13),(2,22),(3,8),(4,88),(5,6),(7,21),(9,64),(10,14),(11,15),(12,8), +(6,20),(8,39),(13,0),(14,3),(15,54),(16,85),(17,1),(18,1),(19,0),(20,0); +CREATE TABLE t2 (c INT) ENGINE=Aria; +INSERT INTO t2 VALUES (1),(2),(3); +EXPLAIN SELECT a FROM t1 JOIN t2 WHERE a = b AND c <> 7 GROUP BY a HAVING a != 6 AND a <= 9; +SELECT a FROM t1 JOIN t2 WHERE a = b AND c <> 7 GROUP BY a HAVING a != 6 AND a <= 9; +DROP TABLE t1, t2; + +--echo # +--echo # End of 11.0 tests +--echo # diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index bf4a490ebec..5622605e651 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -2831,8 +2831,8 @@ alter table t2 drop index idx1, drop index idx2, add index idx3(d,e); explain select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using index condition; Using where -1 SIMPLE t1 ref idx idx 5 test.t2.d 11 +1 SIMPLE t1 range idx idx 5 NULL 15 Using index condition +1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using where; Using join buffer (flat, BNL join) explain format=json select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; EXPLAIN @@ -2841,35 +2841,40 @@ EXPLAIN "select_id": 1, "cost": "COST_REPLACED", "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "range", - "possible_keys": ["idx3"], - "key": "idx3", - "key_length": "10", - "used_key_parts": ["d", "e"], - "loops": 1, - "rows": 5, - "cost": "COST_REPLACED", - "filtered": 100, - "index_condition": "t2.d is not null", - "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1" - } - }, { "table": { "table_name": "t1", - "access_type": "ref", + "access_type": "range", "possible_keys": ["idx"], "key": "idx", "key_length": "5", "used_key_parts": ["a"], - "ref": ["test.t2.d"], - "loops": 5, - "rows": 11, + "loops": 1, + "rows": 15, "cost": "COST_REPLACED", - "filtered": 100 + "filtered": 100, + "index_condition": "1" + } + }, + { + "block-nl-join": { + "table": { + "table_name": "t2", + "access_type": "range", + "possible_keys": ["idx3"], + "key": "idx3", + "key_length": "10", + "used_key_parts": ["d", "e"], + "loops": 15, + "rows": 5, + "cost": "COST_REPLACED", + "filtered": 60, + "attached_condition": "octet_length(t2.f) = 1" + }, + "buffer_type": "flat", + "buffer_size": "461", + "join_type": "BNL", + "attached_condition": "t2.d = t1.a and (t1.a,t2.e) in (((4,4)),((7,7)),((8,8)))" } } ] @@ -2878,14 +2883,14 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; a b c d e f -7 7 xxxyy 7 7 h +7 7 xxxya 7 7 h 7 7 xxxya 7 7 h 7 7 xxxyy 7 7 h -7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h +7 8 xxxxa 7 7 h 7 8 xxxxa 7 7 h 7 8 xxxxx 7 7 h -7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h # join order: (t1,t2) with ref access of t2 # range access to t1 by 1-component keys for index idx explain select * from t1,t2 diff --git a/mysql-test/main/range.test b/mysql-test/main/range.test index f20970939d9..28ee8e5cbeb 100644 --- a/mysql-test/main/range.test +++ b/mysql-test/main/range.test @@ -2024,6 +2024,7 @@ select * from t1,t2 eval explain $q7; --source include/explain-no-costs.inc eval explain format=json $q7; +--sorted_result eval $q7; --echo # join order: (t1,t2) with ref access of t2 diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index 569080cc283..81352cedc48 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -2824,8 +2824,8 @@ alter table t2 drop index idx1, drop index idx2, add index idx3(d,e); explain select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using index condition; Using where; Rowid-ordered scan -1 SIMPLE t1 ref idx idx 5 test.t2.d 11 +1 SIMPLE t1 range idx idx 5 NULL 15 Using index condition; Rowid-ordered scan +1 SIMPLE t2 range idx3 idx3 10 NULL 5 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) explain format=json select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; EXPLAIN @@ -2834,36 +2834,42 @@ EXPLAIN "select_id": 1, "cost": "COST_REPLACED", "nested_loop": [ - { - "table": { - "table_name": "t2", - "access_type": "range", - "possible_keys": ["idx3"], - "key": "idx3", - "key_length": "10", - "used_key_parts": ["d", "e"], - "loops": 1, - "rows": 5, - "cost": "COST_REPLACED", - "filtered": 100, - "index_condition": "t2.d is not null", - "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1", - "mrr_type": "Rowid-ordered scan" - } - }, { "table": { "table_name": "t1", - "access_type": "ref", + "access_type": "range", "possible_keys": ["idx"], "key": "idx", "key_length": "5", "used_key_parts": ["a"], - "ref": ["test.t2.d"], - "loops": 5, - "rows": 11, + "loops": 1, + "rows": 15, "cost": "COST_REPLACED", - "filtered": 100 + "filtered": 100, + "index_condition": "1", + "mrr_type": "Rowid-ordered scan" + } + }, + { + "block-nl-join": { + "table": { + "table_name": "t2", + "access_type": "range", + "possible_keys": ["idx3"], + "key": "idx3", + "key_length": "10", + "used_key_parts": ["d", "e"], + "loops": 15, + "rows": 5, + "cost": "COST_REPLACED", + "filtered": 60, + "attached_condition": "octet_length(t2.f) = 1", + "mrr_type": "Rowid-ordered scan" + }, + "buffer_type": "flat", + "buffer_size": "461", + "join_type": "BNL", + "attached_condition": "t2.d = t1.a and (t1.a,t2.e) in (((4,4)),((7,7)),((8,8)))" } } ] @@ -2872,14 +2878,14 @@ EXPLAIN select * from t1,t2 where a = d and (a,e) in ((4,4),(7,7),(8,8)) and length(f) = 1; a b c d e f -7 7 xxxyy 7 7 h +7 7 xxxya 7 7 h 7 7 xxxya 7 7 h 7 7 xxxyy 7 7 h -7 7 xxxya 7 7 h -7 8 xxxxx 7 7 h +7 7 xxxyy 7 7 h +7 8 xxxxa 7 7 h 7 8 xxxxa 7 7 h 7 8 xxxxx 7 7 h -7 8 xxxxa 7 7 h +7 8 xxxxx 7 7 h # join order: (t1,t2) with ref access of t2 # range access to t1 by 1-component keys for index idx explain select * from t1,t2 diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index cef56e27d91..423a0777d5e 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -1367,8 +1367,8 @@ GROUP BY SQ1_t1.f4)); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 SUBQUERY SQ1_t3 range f4 f4 5 NULL 2 Using where; Using index; Using temporary -3 SUBQUERY SQ1_t1 index NULL f4 5 NULL 2 Using index; Using join buffer (flat, BNL join) +3 SUBQUERY SQ1_t1 index NULL f4 5 NULL 2 Using index; Using temporary +3 SUBQUERY SQ1_t3 range f4 f4 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE (SELECT f2 FROM t2 WHERE f4 <= ALL diff --git a/mysql-test/main/subselect_mat_cost_bugs.result b/mysql-test/main/subselect_mat_cost_bugs.result index 77b3430ba1f..7237a62d222 100644 --- a/mysql-test/main/subselect_mat_cost_bugs.result +++ b/mysql-test/main/subselect_mat_cost_bugs.result @@ -196,8 +196,8 @@ ORDER BY field1 ; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 2 Using where; Using filesort 1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 alias2.f3 1 Using index -3 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 +3 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) 2 DERIVED t2 ALL NULL NULL NULL NULL 2 SELECT alias2.f2 AS field1 FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1 diff --git a/mysql-test/main/subselect_sj2.result b/mysql-test/main/subselect_sj2.result index e2e44fd8e80..978f4b72a98 100644 --- a/mysql-test/main/subselect_sj2.result +++ b/mysql-test/main/subselect_sj2.result @@ -340,9 +340,9 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan; Start temporary -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary -1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where +1 PRIMARY t3 ALL PRIMARY,Percentage NULL NULL NULL 22 Using where +1 PRIMARY t1 ref Population,Country Country 3 test.t3.Country 0 Using where; LooseScan +1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t3.Country 1 Using where set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; CREATE TABLE t1 ( diff --git a/mysql-test/main/subselect_sj2_jcl6.result b/mysql-test/main/subselect_sj2_jcl6.result index a5bcfbfa147..c4d121616e7 100644 --- a/mysql-test/main/subselect_sj2_jcl6.result +++ b/mysql-test/main/subselect_sj2_jcl6.result @@ -346,9 +346,9 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan; Start temporary -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t2 ALL PRIMARY,Population NULL NULL NULL 16 Using where +1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t2); Using join buffer (flat, BNL join) +1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t2.Code,const 1 Using index condition; Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; CREATE TABLE t1 ( diff --git a/mysql-test/main/subselect_sj2_mat.result b/mysql-test/main/subselect_sj2_mat.result index acd600a734f..c639b384522 100644 --- a/mysql-test/main/subselect_sj2_mat.result +++ b/mysql-test/main/subselect_sj2_mat.result @@ -342,9 +342,9 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan; Start temporary -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; End temporary -1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where +1 PRIMARY t3 ALL PRIMARY,Percentage NULL NULL NULL 22 Using where +1 PRIMARY t1 ref Population,Country Country 3 test.t3.Country 0 Using where; LooseScan +1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t3.Country 1 Using where set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; CREATE TABLE t1 ( @@ -1951,12 +1951,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t2_2.id_product 1 Using where; Using index; End temporary 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 8 test.t3.id_product,const 1 Using where; Using index 1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where -1 PRIMARY t2_3 range id_t2,id_product id_t2 5 NULL 33 Using index condition; Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) -1 PRIMARY t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) -1 PRIMARY t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 Using where 1 PRIMARY t5 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t1 index NULL PRIMARY 8 NULL 73 Using where; Using index; Using join buffer (flat, BNL join) 2 MATERIALIZED t2_1 ALL id_t2,id_product NULL NULL NULL 223 Using where +4 MATERIALIZED t2_3 range id_t2,id_product id_t2 5 NULL 33 Using index condition; Using where +5 MATERIALIZED t2_4 range id_t2,id_product id_t2 5 NULL 18 Using index condition; Using where +6 MATERIALIZED t2_5 range id_t2,id_product id_t2 5 NULL 31 Using index condition; Using where set optimizer_switch='rowid_filter=default'; drop table t1,t2,t3,t4,t5; set global innodb_stats_persistent= @innodb_stats_persistent_save; diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 96f3c568446..0c351bcb3cd 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -545,7 +545,7 @@ select * from t1 where id in (select id from t1 as x1 where (t1.cur_date is null)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t1) +1 PRIMARY x1 ALL NULL NULL NULL NULL 2 50.00 Using where; FirstMatch(t1) Warnings: Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where `test`.`x1`.`id` = `test`.`t1`.`id` and `test`.`t1`.`cur_date` = 0 @@ -557,7 +557,7 @@ select * from t2 where id in (select id from t2 as x1 where (t2.cur_date is null)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(t2) +1 PRIMARY x1 ALL NULL NULL NULL NULL 2 50.00 Using where; FirstMatch(t2) Warnings: Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where `test`.`x1`.`id` = `test`.`t2`.`id` and `test`.`t2`.`cur_date` = 0 diff --git a/mysql-test/suite/maria/mrr.result b/mysql-test/suite/maria/mrr.result index 2c8c289f4a6..de468512e92 100644 --- a/mysql-test/suite/maria/mrr.result +++ b/mysql-test/suite/maria/mrr.result @@ -364,8 +364,8 @@ EXPLAIN SELECT COUNT(t1.v) FROM t1, t2 IGNORE INDEX (idx), t3 IGNORE INDEX (idx) WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 16 Using index condition; Rowid-ordered scan -1 SIMPLE t1 index NULL idx 7 NULL 15 Using index; Using join buffer (flat, BNL join) +1 SIMPLE t1 index NULL idx 7 NULL 15 Using index +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 16 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) 1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 25 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join) SELECT COUNT(t1.v) FROM t1, t2, t3 WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index de0229e9e2d..a7cfbc44971 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -12193,6 +12193,27 @@ void ha_partition::update_optimizer_costs(OPTIMIZER_COSTS *costs) m_file[i]->update_optimizer_costs(costs); } +ulonglong ha_partition::row_blocks() +{ + ulonglong active_partitions= bitmap_bits_set(&m_part_info->read_partitions); + return handler::row_blocks() + MY_MAX(active_partitions,1)-1; +} + +ulonglong ha_partition::index_blocks(uint index, uint ranges, ha_rows rows) +{ + ulonglong blocks= 0; + ulonglong active_partitions= bitmap_bits_set(&m_part_info->read_partitions); + /* Assume rows are evenly dived among partitions */ + rows= (rows+ active_partitions -1) / active_partitions; + + for (uint i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + blocks+= m_file[i]->index_blocks(index, ranges, rows); + return blocks; +} + + struct st_mysql_storage_engine partition_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index bb8cd2b2db1..8a3482fd9e5 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1648,6 +1648,8 @@ public: const Column_definition &new_field) const override; void set_optimizer_costs(THD *thd) override; void update_optimizer_costs(OPTIMIZER_COSTS *costs) override; + virtual ulonglong index_blocks(uint index, uint ranges, ha_rows rows) override; + virtual ulonglong row_blocks() override; }; #endif /* HA_PARTITION_INCLUDED */ diff --git a/sql/handler.h b/sql/handler.h index 0810d1a503a..717119bcf99 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2818,7 +2818,7 @@ public: double comp_cost; /* Cost of comparing found rows with WHERE clause */ double copy_cost; /* Copying the data to 'record' */ double limit_cost; /* Total cost when restricting rows with limit */ - + double setup_cost; /* MULTI_RANGE_READ_SETUP_COST or similar */ IO_AND_CPU_COST index_cost; IO_AND_CPU_COST row_cost; @@ -2835,8 +2835,8 @@ public: double total_cost() const { return ((index_cost.io + row_cost.io) * avg_io_cost+ - index_cost.cpu + row_cost.cpu + comp_cost + copy_cost + - cpu_cost); + index_cost.cpu + row_cost.cpu + copy_cost + + comp_cost + cpu_cost + setup_cost); } /* Cost for just fetching and copying a row (no compare costs) */ @@ -2881,6 +2881,7 @@ public: copy_cost+= cost->copy_cost; comp_cost+= cost->comp_cost; cpu_cost+= cost->cpu_cost; + setup_cost+= cost->setup_cost; } inline void reset() @@ -2888,6 +2889,7 @@ public: avg_io_cost= 0; comp_cost= cpu_cost= 0.0; copy_cost= limit_cost= 0.0; + setup_cost= 0.0; index_cost= {0,0}; row_cost= {0,0}; } @@ -3333,10 +3335,11 @@ private: For non partitioned handlers this is &TABLE_SHARE::ha_share. */ Handler_share **ha_share; +public: + double optimizer_where_cost; // Copy of THD->...optimzer_where_cost double optimizer_scan_setup_cost; // Copy of THD->...optimzer_scan_... -public: handler(handlerton *ht_arg, TABLE_SHARE *share_arg) :table_share(share_arg), table(0), estimation_rows_to_insert(0), @@ -3603,6 +3606,18 @@ public: return ((cost->index_cost.cpu + cost->row_cost.cpu + cost->copy_cost) + blocks * DISK_READ_COST * DISK_READ_RATIO); } + /* + Same as above but without capping. + This is only used for comparing cost with s->quick_read time, which + does not do any capping. + */ + + inline double cost_no_capping(ALL_READ_COST *cost) + { + double blocks= (cost->index_cost.io + cost->row_cost.io); + return ((cost->index_cost.cpu + cost->row_cost.cpu + cost->copy_cost) + + blocks * DISK_READ_COST * DISK_READ_RATIO); + } /* Calculate cost when we are going to excute the given read method @@ -3621,7 +3636,7 @@ public: blocks * DISK_READ_COST * DISK_READ_RATIO); } - inline ulonglong row_blocks() + virtual ulonglong row_blocks() { return (stats.data_file_length + IO_SIZE-1) / IO_SIZE; } diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 7f930c9d9ae..3bc4f8328b1 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -83,8 +83,8 @@ void handler::calculate_costs(Cost_estimate *cost, uint keyno, /* Adjust io cost to data size */ cost->index_cost.io= MY_MIN(cost->index_cost.io, index_blocks(keyno)); - cost->comp_cost= (rows2double(total_rows) * WHERE_COST + - MULTI_RANGE_READ_SETUP_COST); + cost->comp_cost= rows2double(total_rows) * WHERE_COST; + cost->setup_cost= MULTI_RANGE_READ_SETUP_COST; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4cbf618e045..a7b3fc1d106 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11939,14 +11939,21 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, ha_rows table_records= param->table->stat_records(); if (rows > table_records) { + ha_rows diff= rows - table_records; /* For any index the total number of records within all ranges cannot be be bigger than the number of records in the table. This check is needed as sometimes that table statistics or range estimates may be slightly out of sync. + + We cannot do this easily in the above multi_range_read_info_const() + call as then we would need to have similar adjustmends done + in the partitioning engine. */ rows= MY_MAX(table_records, 1); param->quick_rows[keynr]= rows; + /* Adjust costs */ + cost->comp_cost-= file->WHERE_COST * diff; } param->possible_keys.set_bit(keynr); if (update_tbl_stats) diff --git a/sql/opt_range.h b/sql/opt_range.h index b3a7939c869..a8515f48618 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1880,12 +1880,13 @@ class SQL_SELECT :public Sql_alloc { In other cases, NULL. */ Item *pre_idx_push_select_cond; - TABLE *head; - IO_CACHE file; // Positions to used records - ha_rows records; // Records in use if read from file - double read_time; // Time to read rows - key_map quick_keys; // Possible quick keys - key_map needed_reg; // Possible quick keys after prev tables. + TABLE *head; + IO_CACHE file; // Positions to used records + ha_rows records; // Records in use if read from file + ALL_READ_COST read_cost; // Cost of reading rows + double read_time; // Time to read rows (from read_cost) + key_map quick_keys; // Possible quick keys + key_map needed_reg; // Possible quick keys after prev tables. table_map const_tables,read_tables; /* See PARAM::possible_keys */ key_map possible_keys; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 94adae02a17..38a6f9b1ef2 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4116,10 +4116,15 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) if (join->best_positions[idx].use_join_buffer && !join->best_positions[idx].firstmatch_with_join_buf) { - best_access_path(join, join->best_positions[idx].table, - rem_tables, join->best_positions, idx, - TRUE /* no jbuf */, - record_count, join->best_positions + idx, &dummy); + /* + records_out cannot be bigger just because we remove join buffer + */ + double records_out= join->best_positions[idx].records_out; + best_access_path(join, join->best_positions[idx].table, + rem_tables, join->best_positions, idx, + TRUE /* no jbuf */, + record_count, join->best_positions + idx, &dummy); + set_if_smaller(join->best_positions[idx].records_out, records_out); } record_count *= join->best_positions[idx].records_out; rem_tables &= ~join->best_positions[idx].table->table->map; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9d1987a6369..3d1096dfa0a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -106,6 +106,13 @@ #define double_to_ulonglong(A) ((A) >= ((double)ULONGLONG_MAX) ? ULONGLONG_MAX : (ulonglong) (A)) +/* Used to ensure that costs are calculate the same way */ +inline bool compare_cost(double a, double b) +{ + DBUG_ASSERT(a >= 0.0 && b >= 0.0); + return (a >= b - b/10000000.0 && a <= b+b/10000000.0); +} + inline double safe_filtered(double a, double b) { return b != 0 ? a/b*100.0 : 0.0; @@ -8985,7 +8992,8 @@ best_access_path(JOIN *join, copy_cost= (record_count * records_after_filter * WHERE_COST_THD(thd) + startup_cost); - cur_cost= (file->cost_for_reading_multiple_times(prev_record_count, &tmp) + + cur_cost= (file->cost_for_reading_multiple_times(prev_record_count, + &tmp) + copy_cost); if (unlikely(trace_access_idx.trace_started())) @@ -9242,6 +9250,7 @@ best_access_path(JOIN *join, uint forced_index= MAX_KEY; bool force_plan= 0, use_join_buffer= 0; ulonglong refills= 1; + ALL_READ_COST cost; /* Range optimizer never proposes a RANGE if it isn't better @@ -9255,16 +9264,7 @@ best_access_path(JOIN *join, For each record we: - read record range through 'quick' - skip rows which does not satisfy WHERE constraints - - Note that s->quick->read_time includes the cost of comparing - the row with the where clause (WHERE_COST) - - TODO: - We take into account possible use of join cache for ALL/index - access (see first else-branch below), but we don't take it into - account here for range/index_merge access. Find out why this is so. */ - cur_cost= COST_MULT(s->quick->read_time, record_count); /* Use record count from range optimizer. @@ -9288,33 +9288,38 @@ best_access_path(JOIN *join, DBUG_ASSERT(range->rows >= s->found_records); DBUG_ASSERT((range->cost.total_cost() == 0.0 && s->quick->read_time == 0.0) || - (range->cost.total_cost() / s->quick->read_time <= 1.0000001 && - range->cost.total_cost() / s->quick->read_time >= 0.9999999)); + compare_cost(range->cost.total_cost(), + s->quick->read_time)); + DBUG_ASSERT(compare_cost(range->cost.comp_cost, + range->rows * file->WHERE_COST)); + + /* Get range cost. This does not include cost of the WHERE */ + range->get_costs(&cost); + /* Ensure that cost from opt_range are correct */ + DBUG_ASSERT(compare_cost(file->cost_no_capping(&cost) + + range->cost.comp_cost + + range->cost.setup_cost, + s->quick->read_time)); - range->get_costs(&tmp); if (table->can_use_rowid_filter(key_no)) { filter= table->best_range_rowid_filter(key_no, rows2double(range->rows), - file->cost(&tmp), - file->cost(tmp.index_cost), + file->cost(&cost), + file->cost(cost.index_cost), record_count, &records_best_filter); set_if_smaller(best.records_out, records_best_filter); if (filter) { - filter= filter->apply_filter(thd, table, &tmp, + filter= filter->apply_filter(thd, table, &cost, &records_after_filter, &startup_cost, range->ranges, record_count); if (filter) { - tmp.row_cost.cpu+= records_after_filter * WHERE_COST_THD(thd); - cur_cost= file->cost_for_reading_multiple_times(record_count, - &tmp); - cur_cost= COST_ADD(cur_cost, startup_cost); - startup_cost= 0; // Avoid adding it again later + set_if_smaller(best.records_out, records_after_filter); table->opt_range[key_no].selectivity= filter->selectivity; } } @@ -9331,10 +9336,24 @@ best_access_path(JOIN *join, force_plan= 1; } type= JT_RANGE; + /* + We cannot use range->cost.cmp_cost here as records_after_filter + is be different if filter is used. + */ + cost.copy_cost+= (records_after_filter * file->WHERE_COST + + range->cost.setup_cost); } else { type= JT_INDEX_MERGE; + /* + We don't know exactly from where the costs comes from. + Let's store it in copy_cost. + Note that s->quick->read_time includes the cost of comparing + the row with the where clause (WHERE_COST) + */ + cost.reset(); + cost.copy_cost= s->quick->read_time; } loose_scan_opt.check_range_access(join, idx, s->quick); } @@ -9360,7 +9379,7 @@ best_access_path(JOIN *join, if (s->cached_forced_index_type) { type= s->cached_forced_index_type; - cur_cost= s->cached_forced_index_cost; + cost= s->cached_forced_index_cost; forced_index= s->cached_forced_index; } else @@ -9376,7 +9395,7 @@ best_access_path(JOIN *join, { /* Use value from estimate_scan_time */ forced_index= s->cached_covering_key; - cur_cost= s->cached_scan_and_compare_time; + cost= s->cached_scan_and_compare_cost; } else { @@ -9386,93 +9405,93 @@ best_access_path(JOIN *join, keys.intersect(table->keys_in_use_for_query); if ((forced_index= find_shortest_key(table, &keys)) < MAX_KEY) { - ALL_READ_COST cost= cost_for_index_read(thd, table, - forced_index, - s->records, 0); - cur_cost= file->cost(cost); + cost= cost_for_index_read(thd, table, + forced_index, + s->records, 0); /* Calculate cost of checking the attached WHERE */ - cur_cost= COST_ADD(cur_cost, - s->records * WHERE_COST_THD(thd)); + cost.copy_cost+= s->records * file->WHERE_COST; } else #endif { /* No usable key, use table scan */ - cur_cost= s->cached_scan_and_compare_time; + cost= s->cached_scan_and_compare_cost; type= JT_ALL; } } } else // table scan { - cur_cost= s->cached_scan_and_compare_time; + cost= s->cached_scan_and_compare_cost; type= JT_ALL; } /* Cache result for other calls */ s->cached_forced_index_type= type; - s->cached_forced_index_cost= cur_cost; + s->cached_forced_index_cost= cost; s->cached_forced_index= forced_index; } + } - if (disable_jbuf || (table->map & join->outer_join)) - { - /* - Simple scan - We estimate we have to read org_records rows. - records_after_filter rows will survive the where check of constants. - 'best.records_out' rows will survive after the check against columns - from previous tables. - */ - scan_type= "scan"; + if (disable_jbuf || (table->map & join->outer_join)) + { + /* + Simple scan + We estimate we have to read org_records rows. + records_after_filter rows will survive the where check of constants. + 'best.records_out' rows will survive after the check against columns + from previous tables. + */ + scan_type= "scan"; - /* - We have to compare each row set against all previous row combinations - */ - cur_cost= COST_MULT(cur_cost, record_count); - } - else - { - /* Scan trough join cache */ - double cmp_time, row_copy_cost, tmp_refills; + /* + We have to compare each row set against all previous row combinations + */ + cur_cost= file->cost_for_reading_multiple_times(record_count, + &cost); + } + else + { + /* Scan trough join cache */ + double cmp_time, row_copy_cost, tmp_refills; - /* - Note that the cost of checking all rows against the table specific - WHERE is already included in cur_cost. - */ - scan_type= "scan_with_join_cache"; + /* + Note that the cost of checking all rows against the table specific + WHERE is already included in cur_cost. + */ + scan_type= "scan_with_join_cache"; - /* Calculate cost of refills */ - tmp_refills= (1.0 + floor((double) cache_record_length(join,idx) * - (record_count / - (double) thd->variables.join_buff_size))); - cur_cost= COST_MULT(cur_cost, tmp_refills); - refills= double_to_ulonglong(ceil(tmp_refills)); + /* Calculate cost of refills */ + tmp_refills= (1.0 + floor((double) cache_record_length(join,idx) * + (record_count / + (double) thd->variables.join_buff_size))); + cur_cost= file->cost_for_reading_multiple_times(tmp_refills, + &cost); + refills= double_to_ulonglong(ceil(tmp_refills)); - /* We come here only if there are already rows in the join cache */ - DBUG_ASSERT(idx != join->const_tables); - /* - records_after_filter is the number of rows that have survived - the table specific WHERE check that only involves constants. + /* We come here only if there are already rows in the join cache */ + DBUG_ASSERT(idx != join->const_tables); + /* + records_after_filter is the number of rows that have survived + the table specific WHERE check that only involves constants. - Calculate cost of: - - Copying all previous record combinations to the join cache - - Copying the tables from the join cache to table records - - Checking the WHERE against the final row combination - */ - row_copy_cost= (ROW_COPY_COST_THD(thd) * - JOIN_CACHE_ROW_COPY_COST_FACTOR(thd)); - cmp_time= (record_count * row_copy_cost + - records_after_filter * record_count * - ((idx - join->const_tables) * row_copy_cost + - WHERE_COST_THD(thd))); - cur_cost= COST_ADD(cur_cost, cmp_time); - use_join_buffer= 1; - } + Calculate cost of: + - Copying all previous record combinations to the join cache + - Copying the tables from the join cache to table records + - Checking the WHERE against the final row combination + */ + row_copy_cost= (ROW_COPY_COST_THD(thd) * + JOIN_CACHE_ROW_COPY_COST_FACTOR(thd)); + cmp_time= (record_count * row_copy_cost + + records_after_filter * record_count * + ((idx - join->const_tables) * row_copy_cost + + WHERE_COST_THD(thd))); + cur_cost= COST_ADD(cur_cost, cmp_time); + use_join_buffer= 1; } /* Splitting technique cannot be used with join cache */ if (table->is_splittable()) - startup_cost= table->get_materialization_cost(); + startup_cost+= table->get_materialization_cost(); cur_cost+= startup_cost; if (unlikely(trace_access_scan.trace_started())) @@ -9488,6 +9507,10 @@ best_access_path(JOIN *join, add("rows_after_filter", records_after_filter). add("rows_out", best.records_out). add("cost", cur_cost); + if (use_join_buffer) + trace_access_scan. + add("cost_without_join_buffer", + file->cost_for_reading_multiple_times(record_count, &cost)); if (type == JT_ALL) { trace_access_scan.add("index_only", @@ -15745,7 +15768,9 @@ void JOIN_TAB::estimate_scan_time() { THD *thd= join->thd; handler *file= table->file; - double copy_cost; + double row_copy_cost, copy_cost; + ALL_READ_COST * const cost= &cached_scan_and_compare_cost; + cost->reset(); cached_covering_key= MAX_KEY; if (table->is_created()) @@ -15756,7 +15781,8 @@ void JOIN_TAB::estimate_scan_time() &startup_cost); table->opt_range_condition_rows= records; table->used_stat_records= records; - copy_cost= file->ROW_COPY_COST; + cost->row_cost.cpu= read_time; + row_copy_cost= file->ROW_COPY_COST; } else { @@ -15770,14 +15796,15 @@ void JOIN_TAB::estimate_scan_time() if (!table->covering_keys.is_clear_all() && ! table->no_keyread) { cached_covering_key= find_shortest_key(table, &table->covering_keys); - read_time= file->cost(file->ha_key_scan_time(cached_covering_key, - records)); - copy_cost= 0; // included in ha_key_scan_time + cost->index_cost= file->ha_key_scan_time(cached_covering_key, records); + read_time= file->cost(cost->index_cost); + row_copy_cost= 0; // Included in ha_key_scan_time } else { - read_time= file->cost(file->ha_scan_time(records)); - copy_cost= 0; + cost->row_cost= file->ha_scan_time(records); + read_time= file->cost(cost->row_cost); + row_copy_cost= 0; // Included in ha_scan_time } } } @@ -15798,14 +15825,24 @@ void JOIN_TAB::estimate_scan_time() records= table->stat_records(); DBUG_ASSERT(table->opt_range_condition_rows == records); - // Needs fix.. - read_time= file->cost(table->file->ha_scan_time(MY_MAX(records, 1000))); - copy_cost= table->s->optimizer_costs.row_copy_cost; + cost->row_cost= table->file->ha_scan_time(MY_MAX(records, 1000)); + read_time= file->cost(cost->row_cost); + row_copy_cost= table->s->optimizer_costs.row_copy_cost; } found_records= records; - cached_scan_and_compare_time= (read_time + records * - (copy_cost + WHERE_COST_THD(thd))); + copy_cost= (records * (row_copy_cost + WHERE_COST_THD(thd))); + cached_scan_and_compare_time= read_time + copy_cost; + cost->copy_cost+= copy_cost; + + /* + Assume we only need to do physical IO once even if we scan the file + multiple times. + */ + cost->max_index_blocks= (longlong) ceil(cost->index_cost.io); + cost->max_row_blocks= (longlong) ceil(cost->row_cost.io); + DBUG_ASSERT(compare_cost(cached_scan_and_compare_time, + file->cost(cost))); } diff --git a/sql/sql_select.h b/sql/sql_select.h index 9dd4171e47f..34a029cc774 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -368,8 +368,10 @@ typedef struct st_join_table { /* set by estimate_scan_time() */ double cached_scan_and_compare_time; - double cached_forced_index_cost; + ALL_READ_COST cached_scan_and_compare_cost; + /* Used with force_index_join */ + ALL_READ_COST cached_forced_index_cost; /* dependent is the table that must be read before the current one Used for example with STRAIGHT_JOIN or outer joins diff --git a/sql/table.cc b/sql/table.cc index 4296007984b..d6a408e575d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -357,7 +357,7 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, strmov(path_buff, path); share->normalized_path.str= share->path.str; share->normalized_path.length= path_length; - share->table_category= get_table_category(& share->db, & share->table_name); + share->table_category= get_table_category(&share->db, &share->table_name); share->open_errno= ENOENT; /* The following will be updated in open_table_from_share */ share->can_do_row_logging= 1; @@ -10577,6 +10577,13 @@ double TABLE::OPT_RANGE::index_only_fetch_cost(TABLE *table) (double) rows * table->s->optimizer_costs.key_copy_cost); } + +/* + Convert range cost to ALL_READ_COST + Note that the returned cost does not include the WHERE cost + (costs.comp_cost). +*/ + void TABLE::OPT_RANGE::get_costs(ALL_READ_COST *res) { res->index_cost= cost.index_cost;