452 lines
12 KiB
Plaintext
452 lines
12 KiB
Plaintext
#
|
|
# Bug#20443863 USE OF WORST_SEEKS IN FIND_BEST_REF() CAN LEAD TO
|
|
# WRONG QUERY PLAN
|
|
#
|
|
CREATE TABLE t1 (
|
|
i1 INTEGER,
|
|
i2 INTEGER,
|
|
i3 INTEGER,
|
|
KEY(i1,i2)
|
|
) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES (1, 1, 1), (1, 1, 1),(1, 1, 1),(1, 1, 1),
|
|
(2, 2, 1), (2, 2, 1),(2, 2, 1),(2, 2, 1),
|
|
(3, 3, 1), (3, 3, 1),(3, 3, 1),(3, 3, 1);
|
|
EXPLAIN FORMAT=JSON SELECT i3 FROM t1 WHERE i1 = 1 AND i2 = 1;
|
|
EXPLAIN
|
|
{
|
|
"query_block": {
|
|
"select_id": 1,
|
|
"cost_info": {
|
|
"query_cost": "0.90"
|
|
},
|
|
"table": {
|
|
"table_name": "t1",
|
|
"access_type": "ref",
|
|
"possible_keys": [
|
|
"i1"
|
|
],
|
|
"key": "i1",
|
|
"used_key_parts": [
|
|
"i1",
|
|
"i2"
|
|
],
|
|
"key_length": "10",
|
|
"ref": [
|
|
"const",
|
|
"const"
|
|
],
|
|
"rows_examined_per_scan": 4,
|
|
"rows_produced_per_join": 4,
|
|
"filtered": "100.00",
|
|
"cost_info": {
|
|
"read_cost": "0.50",
|
|
"eval_cost": "0.40",
|
|
"prefix_cost": "0.90",
|
|
"data_read_per_join": "64"
|
|
},
|
|
"used_columns": [
|
|
"i1",
|
|
"i2",
|
|
"i3"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t1`.`i3` AS `i3` from `test`.`t1` where ((`test`.`t1`.`i2` = 1) and (`test`.`t1`.`i1` = 1))
|
|
EXPLAIN FORMAT=JSON SELECT i3 FROM t1 WHERE i1 = 1 AND i3 = 1;
|
|
EXPLAIN
|
|
{
|
|
"query_block": {
|
|
"select_id": 1,
|
|
"cost_info": {
|
|
"query_cost": "0.90"
|
|
},
|
|
"table": {
|
|
"table_name": "t1",
|
|
"access_type": "ref",
|
|
"possible_keys": [
|
|
"i1"
|
|
],
|
|
"key": "i1",
|
|
"used_key_parts": [
|
|
"i1"
|
|
],
|
|
"key_length": "5",
|
|
"ref": [
|
|
"const"
|
|
],
|
|
"rows_examined_per_scan": 4,
|
|
"rows_produced_per_join": 0,
|
|
"filtered": "10.00",
|
|
"cost_info": {
|
|
"read_cost": "0.50",
|
|
"eval_cost": "0.04",
|
|
"prefix_cost": "0.90",
|
|
"data_read_per_join": "6"
|
|
},
|
|
"used_columns": [
|
|
"i1",
|
|
"i3"
|
|
],
|
|
"attached_condition": "(`test`.`t1`.`i3` = 1)"
|
|
}
|
|
}
|
|
}
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t1`.`i3` AS `i3` from `test`.`t1` where ((`test`.`t1`.`i3` = 1) and (`test`.`t1`.`i1` = 1))
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.1
|
|
WHERE cost_name="row_evaluate_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.05
|
|
WHERE cost_name="key_compare_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=1.0
|
|
WHERE cost_name="memory_temptable_create_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.1
|
|
WHERE cost_name="memory_temptable_row_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=20
|
|
WHERE cost_name="disk_temptable_create_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.5
|
|
WHERE cost_name="disk_temptable_row_cost";
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value=0.25
|
|
WHERE cost_name="memory_block_read_cost";
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value=1.0
|
|
WHERE cost_name="io_block_read_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value = 2 * cost_value;
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value = 2 * cost_value;
|
|
SELECT cost_name, cost_value FROM mysql.server_cost;
|
|
cost_name cost_value
|
|
disk_temptable_create_cost 40
|
|
disk_temptable_row_cost 1
|
|
key_compare_cost 0.1
|
|
memory_temptable_create_cost 2
|
|
memory_temptable_row_cost 0.2
|
|
row_evaluate_cost 0.2
|
|
SELECT cost_name, cost_value FROM mysql.engine_cost;
|
|
cost_name cost_value
|
|
io_block_read_cost 2
|
|
memory_block_read_cost 0.5
|
|
FLUSH OPTIMIZER_COSTS;
|
|
EXPLAIN FORMAT=JSON SELECT i3 FROM t1 WHERE i1 = 1 AND i2 = 1;
|
|
EXPLAIN
|
|
{
|
|
"query_block": {
|
|
"select_id": 1,
|
|
"cost_info": {
|
|
"query_cost": "1.80"
|
|
},
|
|
"table": {
|
|
"table_name": "t1",
|
|
"access_type": "ref",
|
|
"possible_keys": [
|
|
"i1"
|
|
],
|
|
"key": "i1",
|
|
"used_key_parts": [
|
|
"i1",
|
|
"i2"
|
|
],
|
|
"key_length": "10",
|
|
"ref": [
|
|
"const",
|
|
"const"
|
|
],
|
|
"rows_examined_per_scan": 4,
|
|
"rows_produced_per_join": 4,
|
|
"filtered": "100.00",
|
|
"cost_info": {
|
|
"read_cost": "1.00",
|
|
"eval_cost": "0.80",
|
|
"prefix_cost": "1.80",
|
|
"data_read_per_join": "64"
|
|
},
|
|
"used_columns": [
|
|
"i1",
|
|
"i2",
|
|
"i3"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t1`.`i3` AS `i3` from `test`.`t1` where ((`test`.`t1`.`i2` = 1) and (`test`.`t1`.`i1` = 1))
|
|
EXPLAIN FORMAT=JSON SELECT i3 FROM t1 WHERE i1 = 1 AND i3 = 1;
|
|
EXPLAIN
|
|
{
|
|
"query_block": {
|
|
"select_id": 1,
|
|
"cost_info": {
|
|
"query_cost": "1.80"
|
|
},
|
|
"table": {
|
|
"table_name": "t1",
|
|
"access_type": "ref",
|
|
"possible_keys": [
|
|
"i1"
|
|
],
|
|
"key": "i1",
|
|
"used_key_parts": [
|
|
"i1"
|
|
],
|
|
"key_length": "5",
|
|
"ref": [
|
|
"const"
|
|
],
|
|
"rows_examined_per_scan": 4,
|
|
"rows_produced_per_join": 0,
|
|
"filtered": "10.00",
|
|
"cost_info": {
|
|
"read_cost": "1.00",
|
|
"eval_cost": "0.08",
|
|
"prefix_cost": "1.80",
|
|
"data_read_per_join": "6"
|
|
},
|
|
"used_columns": [
|
|
"i1",
|
|
"i3"
|
|
],
|
|
"attached_condition": "(`test`.`t1`.`i3` = 1)"
|
|
}
|
|
}
|
|
}
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t1`.`i3` AS `i3` from `test`.`t1` where ((`test`.`t1`.`i3` = 1) and (`test`.`t1`.`i1` = 1))
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=DEFAULT;
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value=DEFAULT;
|
|
FLUSH OPTIMIZER_COSTS;
|
|
DROP TABLE t1;
|
|
#
|
|
# Bug#20947871 INDEX SCAN COST IN TEST_IF_CHEAPER_ORDERING() DOES
|
|
# NOT USE COST CONSTANTS
|
|
#
|
|
CREATE TABLE t1 (
|
|
pk INTEGER PRIMARY KEY,
|
|
a INTEGER,
|
|
b INTEGER,
|
|
c CHAR(255),
|
|
UNIQUE KEY k1 (a)
|
|
);
|
|
INSERT INTO t1 VALUES (1, 1, NULL, "Abc"), (2, 2, NULL, "Abc"),
|
|
(3, 3, NULL, "Abc"), (4, 4, NULL, "Abc");
|
|
INSERT INTO t1 SELECT a + 4, a + 4, b, c FROM t1;
|
|
INSERT INTO t1 SELECT a + 8, a + 8, b, c FROM t1;
|
|
INSERT INTO t1 SELECT a + 16, a + 16, b, c FROM t1;
|
|
INSERT INTO t1 SELECT a + 32, a + 32, b, c FROM t1;
|
|
INSERT INTO t1 SELECT a + 64, a + 64, b, c FROM t1;
|
|
INSERT INTO t1 SELECT a + 128, a + 128, b, c FROM t1;
|
|
CREATE TABLE t2 (
|
|
d INTEGER PRIMARY KEY,
|
|
e INTEGER
|
|
);
|
|
INSERT INTO t2 SELECT a, b FROM t1;
|
|
# Query should be optimized for the LIMIT. Query plan should
|
|
# use index without filesort
|
|
EXPLAIN FORMAT=JSON SELECT * FROM t1 JOIN t2 ON b=d ORDER BY a LIMIT 4;
|
|
EXPLAIN
|
|
{
|
|
"query_block": {
|
|
"select_id": 1,
|
|
"cost_info": {
|
|
"query_cost": "116.95"
|
|
},
|
|
"ordering_operation": {
|
|
"using_filesort": false,
|
|
"nested_loop": [
|
|
{
|
|
"table": {
|
|
"table_name": "t1",
|
|
"access_type": "index",
|
|
"key": "k1",
|
|
"used_key_parts": [
|
|
"a"
|
|
],
|
|
"key_length": "5",
|
|
"rows_examined_per_scan": 4,
|
|
"rows_produced_per_join": 256,
|
|
"filtered": "100.00",
|
|
"cost_info": {
|
|
"read_cost": "1.75",
|
|
"eval_cost": "25.60",
|
|
"prefix_cost": "27.35",
|
|
"data_read_per_join": "260K"
|
|
},
|
|
"used_columns": [
|
|
"pk",
|
|
"a",
|
|
"b",
|
|
"c"
|
|
],
|
|
"attached_condition": "(`test`.`t1`.`b` is not null)"
|
|
}
|
|
},
|
|
{
|
|
"table": {
|
|
"table_name": "t2",
|
|
"access_type": "eq_ref",
|
|
"possible_keys": [
|
|
"PRIMARY"
|
|
],
|
|
"key": "PRIMARY",
|
|
"used_key_parts": [
|
|
"d"
|
|
],
|
|
"key_length": "4",
|
|
"ref": [
|
|
"test.t1.b"
|
|
],
|
|
"rows_examined_per_scan": 1,
|
|
"rows_produced_per_join": 256,
|
|
"filtered": "100.00",
|
|
"cost_info": {
|
|
"read_cost": "64.00",
|
|
"eval_cost": "25.60",
|
|
"prefix_cost": "116.95",
|
|
"data_read_per_join": "4K"
|
|
},
|
|
"used_columns": [
|
|
"d",
|
|
"e"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`e` AS `e` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`d` = `test`.`t1`.`b`) order by `test`.`t1`.`a` limit 4
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.1
|
|
WHERE cost_name="row_evaluate_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.05
|
|
WHERE cost_name="key_compare_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=1.0
|
|
WHERE cost_name="memory_temptable_create_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.1
|
|
WHERE cost_name="memory_temptable_row_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=20
|
|
WHERE cost_name="disk_temptable_create_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=0.5
|
|
WHERE cost_name="disk_temptable_row_cost";
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value=0.25
|
|
WHERE cost_name="memory_block_read_cost";
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value=1.0
|
|
WHERE cost_name="io_block_read_cost";
|
|
UPDATE mysql.server_cost
|
|
SET cost_value = 0.5 * cost_value;
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value = 0.5 * cost_value;
|
|
SELECT cost_name, cost_value FROM mysql.server_cost;
|
|
cost_name cost_value
|
|
disk_temptable_create_cost 10
|
|
disk_temptable_row_cost 0.25
|
|
key_compare_cost 0.025
|
|
memory_temptable_create_cost 0.5
|
|
memory_temptable_row_cost 0.05
|
|
row_evaluate_cost 0.05
|
|
SELECT cost_name, cost_value FROM mysql.engine_cost;
|
|
cost_name cost_value
|
|
io_block_read_cost 0.5
|
|
memory_block_read_cost 0.125
|
|
FLUSH OPTIMIZER_COSTS;
|
|
# This should be optimized for the LIMIT. Query plan should
|
|
# use index without filesort
|
|
EXPLAIN FORMAT=JSON SELECT * FROM t1 JOIN t2 ON b=d ORDER BY a LIMIT 4;
|
|
EXPLAIN
|
|
{
|
|
"query_block": {
|
|
"select_id": 1,
|
|
"cost_info": {
|
|
"query_cost": "58.47"
|
|
},
|
|
"ordering_operation": {
|
|
"using_filesort": false,
|
|
"nested_loop": [
|
|
{
|
|
"table": {
|
|
"table_name": "t1",
|
|
"access_type": "index",
|
|
"key": "k1",
|
|
"used_key_parts": [
|
|
"a"
|
|
],
|
|
"key_length": "5",
|
|
"rows_examined_per_scan": 4,
|
|
"rows_produced_per_join": 256,
|
|
"filtered": "100.00",
|
|
"cost_info": {
|
|
"read_cost": "0.88",
|
|
"eval_cost": "12.80",
|
|
"prefix_cost": "13.68",
|
|
"data_read_per_join": "260K"
|
|
},
|
|
"used_columns": [
|
|
"pk",
|
|
"a",
|
|
"b",
|
|
"c"
|
|
],
|
|
"attached_condition": "(`test`.`t1`.`b` is not null)"
|
|
}
|
|
},
|
|
{
|
|
"table": {
|
|
"table_name": "t2",
|
|
"access_type": "eq_ref",
|
|
"possible_keys": [
|
|
"PRIMARY"
|
|
],
|
|
"key": "PRIMARY",
|
|
"used_key_parts": [
|
|
"d"
|
|
],
|
|
"key_length": "4",
|
|
"ref": [
|
|
"test.t1.b"
|
|
],
|
|
"rows_examined_per_scan": 1,
|
|
"rows_produced_per_join": 256,
|
|
"filtered": "100.00",
|
|
"cost_info": {
|
|
"read_cost": "32.00",
|
|
"eval_cost": "12.80",
|
|
"prefix_cost": "58.48",
|
|
"data_read_per_join": "4K"
|
|
},
|
|
"used_columns": [
|
|
"d",
|
|
"e"
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2`.`e` AS `e` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`d` = `test`.`t1`.`b`) order by `test`.`t1`.`a` limit 4
|
|
UPDATE mysql.server_cost
|
|
SET cost_value=DEFAULT;
|
|
UPDATE mysql.engine_cost
|
|
SET cost_value=DEFAULT;
|
|
FLUSH OPTIMIZER_COSTS;
|
|
DROP TABLE t1, t2;
|