-
Notifications
You must be signed in to change notification settings - Fork 713
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add variable to disable full table/index scans
Summary: There are cases where it is always unacceptable for a client to be doing full table scans. To prevent this from happening, add a new variable optimizer_full_scan. When it is turned off, it will return a new error code ER_FULL_SCAN_DISABLED. For best results, use with optimizer_force_index_for_range. Currently, it does not fallback to alternative plans because we check at the end of query planning. Reviewed By: hermanlee Differential Revision: D7528820 fbshipit-source-id: 94fcd07
- Loading branch information
1 parent
7eab374
commit b90e801
Showing
10 changed files
with
389 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
set @orig_optimizer_full_scan = @@optimizer_full_scan; | ||
set @orig_optimizer_force_index_for_range = @@optimizer_force_index_for_range; | ||
create table t (i int, j int, key(i)); | ||
insert into t values (1, 1); | ||
insert into t values (1, 2); | ||
insert into t values (2, 1); | ||
insert into t values (2, 2); | ||
insert into t values (3, 1); | ||
insert into t values (3, 2); | ||
analyze table t; | ||
Table Op Msg_type Msg_text | ||
test.t analyze status OK | ||
# Basic tests | ||
explain select * from t; | ||
id select_type table type possible_keys key key_len ref rows Extra | ||
1 SIMPLE t ALL NULL NULL NULL NULL # NULL | ||
set optimizer_full_scan = off; | ||
select * from t; | ||
ERROR HY000: Full table/index scan is disabled | ||
set optimizer_full_scan = on; | ||
select * from t; | ||
i j | ||
1 1 | ||
1 2 | ||
2 1 | ||
2 2 | ||
3 1 | ||
3 2 | ||
explain select * from t force index (i); | ||
id select_type table type possible_keys key key_len ref rows Extra | ||
1 SIMPLE t ALL NULL NULL NULL NULL # NULL | ||
set optimizer_full_scan = off; | ||
select i from t force index (i); | ||
ERROR HY000: Full table/index scan is disabled | ||
set optimizer_full_scan = on; | ||
select i from t force index (i); | ||
i | ||
1 | ||
1 | ||
2 | ||
2 | ||
3 | ||
3 | ||
explain select * from t a, t b where a.i = b.i; | ||
id select_type table type possible_keys key key_len ref rows Extra | ||
1 SIMPLE a ALL i NULL NULL NULL # NULL | ||
1 SIMPLE b ALL i NULL NULL NULL # Using where; Using join buffer (Block Nested Loop) | ||
set optimizer_full_scan = off; | ||
select * from t a, t b where a.i = b.i; | ||
ERROR HY000: Full table/index scan is disabled | ||
set optimizer_full_scan = on; | ||
select * from t a, t b where a.i = b.i; | ||
i j i j | ||
1 1 1 1 | ||
1 2 1 1 | ||
1 1 1 2 | ||
1 2 1 2 | ||
2 1 2 1 | ||
2 2 2 1 | ||
2 1 2 2 | ||
2 2 2 2 | ||
3 1 3 1 | ||
3 2 3 1 | ||
3 1 3 2 | ||
3 2 3 2 | ||
explain select * from t a straight_join t b where a.i = 10; | ||
id select_type table type possible_keys key key_len ref rows Extra | ||
1 SIMPLE a ref i i 5 const # NULL | ||
1 SIMPLE b ALL NULL NULL NULL NULL # Using join buffer (Block Nested Loop) | ||
set optimizer_full_scan = off; | ||
select * from t a straight_join t b where a.i = 10; | ||
ERROR HY000: Full table/index scan is disabled | ||
set optimizer_full_scan = on; | ||
select * from t a straight_join t b where a.i = 10; | ||
i j i j | ||
# Test integration with optimizer_force_index_for_range | ||
alter table t drop index i, add primary key (i, j); | ||
# Test range plans | ||
set optimizer_force_index_for_range = on; | ||
set optimizer_full_scan = off; | ||
explain select i from t where i in (1, 2, 3) and j in (1, 2); | ||
id select_type table type possible_keys key key_len ref rows Extra | ||
1 SIMPLE t index PRIMARY PRIMARY 8 NULL # Using where; Using index | ||
select i from t where i in (1, 2, 3) and j in (1, 2); | ||
ERROR HY000: Full table/index scan is disabled | ||
explain select i from t force index (primary) where i in (1, 2, 3) and j in (1, 2); | ||
id select_type table type possible_keys key key_len ref rows Extra | ||
1 SIMPLE t range PRIMARY PRIMARY 8 NULL # Using where; Using index | ||
select i from t force index (primary) where i in (1, 2, 3) and j in (1, 2); | ||
i | ||
1 | ||
1 | ||
2 | ||
2 | ||
3 | ||
3 | ||
drop table t; | ||
set optimizer_full_scan = @orig_optimizer_full_scan; | ||
set optimizer_force_index_for_range = @orig_optimizer_force_index_for_range; |
93 changes: 93 additions & 0 deletions
93
mysql-test/suite/sys_vars/r/optimizer_full_scan_basic.result
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
SET @session_start_value = @@session.optimizer_full_scan; | ||
SELECT @session_start_value; | ||
@session_start_value | ||
1 | ||
SET @global_start_value = @@global.optimizer_full_scan; | ||
SELECT @global_start_value; | ||
@global_start_value | ||
1 | ||
SET @@session.optimizer_full_scan = 0; | ||
SET @@session.optimizer_full_scan = DEFAULT; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SET @@session.optimizer_full_scan = 1; | ||
SET @@session.optimizer_full_scan = DEFAULT; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SET optimizer_full_scan = 1; | ||
SELECT @@optimizer_full_scan; | ||
@@optimizer_full_scan | ||
1 | ||
SELECT session.optimizer_full_scan; | ||
ERROR 42S02: Unknown table 'session' in field list | ||
SELECT local.optimizer_full_scan; | ||
ERROR 42S02: Unknown table 'local' in field list | ||
SET session optimizer_full_scan = 0; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
0 | ||
SET @@session.optimizer_full_scan = 0; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
0 | ||
SET @@session.optimizer_full_scan = 1; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SET @@session.optimizer_full_scan = -1; | ||
ERROR 42000: Variable 'optimizer_full_scan' can't be set to the value of '-1' | ||
SET @@session.optimizer_full_scan = 2; | ||
ERROR 42000: Variable 'optimizer_full_scan' can't be set to the value of '2' | ||
SET @@session.optimizer_full_scan = "T"; | ||
ERROR 42000: Variable 'optimizer_full_scan' can't be set to the value of 'T' | ||
SET @@session.optimizer_full_scan = "Y"; | ||
ERROR 42000: Variable 'optimizer_full_scan' can't be set to the value of 'Y' | ||
SET @@session.optimizer_full_scan = NO; | ||
ERROR 42000: Variable 'optimizer_full_scan' can't be set to the value of 'NO' | ||
SET @@global.optimizer_full_scan = 1; | ||
SELECT @@global.optimizer_full_scan; | ||
@@global.optimizer_full_scan | ||
1 | ||
SET @@global.optimizer_full_scan = 0; | ||
SELECT count(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='optimizer_full_scan'; | ||
count(VARIABLE_VALUE) | ||
1 | ||
SELECT IF(@@session.optimizer_full_scan, "ON", "OFF") = VARIABLE_VALUE | ||
FROM INFORMATION_SCHEMA.SESSION_VARIABLES | ||
WHERE VARIABLE_NAME='optimizer_full_scan'; | ||
IF(@@session.optimizer_full_scan, "ON", "OFF") = VARIABLE_VALUE | ||
1 | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SELECT VARIABLE_VALUE | ||
FROM INFORMATION_SCHEMA.SESSION_VARIABLES | ||
WHERE VARIABLE_NAME='optimizer_full_scan'; | ||
VARIABLE_VALUE | ||
ON | ||
SET @@session.optimizer_full_scan = OFF; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
0 | ||
SET @@session.optimizer_full_scan = ON; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SET @@session.optimizer_full_scan = TRUE; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SET @@session.optimizer_full_scan = FALSE; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
0 | ||
SET @@session.optimizer_full_scan = @session_start_value; | ||
SELECT @@session.optimizer_full_scan; | ||
@@session.optimizer_full_scan | ||
1 | ||
SET @@global.optimizer_full_scan = @global_start_value; | ||
SELECT @@global.optimizer_full_scan; | ||
@@global.optimizer_full_scan | ||
1 |
102 changes: 102 additions & 0 deletions
102
mysql-test/suite/sys_vars/t/optimizer_full_scan_basic.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
--source include/load_sysvars.inc | ||
|
||
|
||
# Saving initial value of optimizer_full_scan in a temporary variable | ||
|
||
SET @session_start_value = @@session.optimizer_full_scan; | ||
SELECT @session_start_value; | ||
SET @global_start_value = @@global.optimizer_full_scan; | ||
SELECT @global_start_value; | ||
|
||
# Display the DEFAULT value of optimizer_full_scan | ||
|
||
SET @@session.optimizer_full_scan = 0; | ||
SET @@session.optimizer_full_scan = DEFAULT; | ||
SELECT @@session.optimizer_full_scan; | ||
|
||
SET @@session.optimizer_full_scan = 1; | ||
SET @@session.optimizer_full_scan = DEFAULT; | ||
SELECT @@session.optimizer_full_scan; | ||
|
||
|
||
# Check if optimizer_full_scan can be accessed with and without @@ sign | ||
|
||
SET optimizer_full_scan = 1; | ||
SELECT @@optimizer_full_scan; | ||
|
||
--Error ER_UNKNOWN_TABLE | ||
SELECT session.optimizer_full_scan; | ||
|
||
--Error ER_UNKNOWN_TABLE | ||
SELECT local.optimizer_full_scan; | ||
|
||
SET session optimizer_full_scan = 0; | ||
SELECT @@session.optimizer_full_scan; | ||
|
||
# change the value of optimizer_full_scan to a valid value | ||
|
||
SET @@session.optimizer_full_scan = 0; | ||
SELECT @@session.optimizer_full_scan; | ||
SET @@session.optimizer_full_scan = 1; | ||
SELECT @@session.optimizer_full_scan; | ||
|
||
|
||
# Change the value of optimizer_full_scan to invalid value | ||
|
||
--Error ER_WRONG_VALUE_FOR_VAR | ||
SET @@session.optimizer_full_scan = -1; | ||
--Error ER_WRONG_VALUE_FOR_VAR | ||
SET @@session.optimizer_full_scan = 2; | ||
--Error ER_WRONG_VALUE_FOR_VAR | ||
SET @@session.optimizer_full_scan = "T"; | ||
--Error ER_WRONG_VALUE_FOR_VAR | ||
SET @@session.optimizer_full_scan = "Y"; | ||
--Error ER_WRONG_VALUE_FOR_VAR | ||
SET @@session.optimizer_full_scan = NO; | ||
|
||
|
||
# Test if accessing global optimizer_full_scan gives error | ||
|
||
SET @@global.optimizer_full_scan = 1; | ||
SELECT @@global.optimizer_full_scan; | ||
SET @@global.optimizer_full_scan = 0; | ||
|
||
|
||
# Check if the value in GLOBAL Table contains variable value | ||
|
||
SELECT count(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='optimizer_full_scan'; | ||
|
||
|
||
# Check if the value in GLOBAL Table matches value in variable | ||
|
||
SELECT IF(@@session.optimizer_full_scan, "ON", "OFF") = VARIABLE_VALUE | ||
FROM INFORMATION_SCHEMA.SESSION_VARIABLES | ||
WHERE VARIABLE_NAME='optimizer_full_scan'; | ||
SELECT @@session.optimizer_full_scan; | ||
SELECT VARIABLE_VALUE | ||
FROM INFORMATION_SCHEMA.SESSION_VARIABLES | ||
WHERE VARIABLE_NAME='optimizer_full_scan'; | ||
|
||
|
||
# Check if ON and OFF values can be used on variable | ||
|
||
SET @@session.optimizer_full_scan = OFF; | ||
SELECT @@session.optimizer_full_scan; | ||
SET @@session.optimizer_full_scan = ON; | ||
SELECT @@session.optimizer_full_scan; | ||
|
||
|
||
# Check if TRUE and FALSE values can be used on variable | ||
|
||
SET @@session.optimizer_full_scan = TRUE; | ||
SELECT @@session.optimizer_full_scan; | ||
SET @@session.optimizer_full_scan = FALSE; | ||
SELECT @@session.optimizer_full_scan; | ||
|
||
|
||
# Restore initial value | ||
|
||
SET @@session.optimizer_full_scan = @session_start_value; | ||
SELECT @@session.optimizer_full_scan; | ||
SET @@global.optimizer_full_scan = @global_start_value; | ||
SELECT @@global.optimizer_full_scan; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
set @orig_optimizer_full_scan = @@optimizer_full_scan; | ||
set @orig_optimizer_force_index_for_range = @@optimizer_force_index_for_range; | ||
|
||
create table t (i int, j int, key(i)); | ||
insert into t values (1, 1); | ||
insert into t values (1, 2); | ||
insert into t values (2, 1); | ||
insert into t values (2, 2); | ||
insert into t values (3, 1); | ||
insert into t values (3, 2); | ||
|
||
analyze table t; | ||
|
||
--echo # Basic tests | ||
--replace_column 9 # | ||
explain select * from t; | ||
set optimizer_full_scan = off; | ||
--error ER_FULL_SCAN_DISABLED | ||
select * from t; | ||
set optimizer_full_scan = on; | ||
select * from t; | ||
|
||
--replace_column 9 # | ||
explain select * from t force index (i); | ||
set optimizer_full_scan = off; | ||
--error ER_FULL_SCAN_DISABLED | ||
select i from t force index (i); | ||
set optimizer_full_scan = on; | ||
select i from t force index (i); | ||
|
||
--replace_column 9 # | ||
explain select * from t a, t b where a.i = b.i; | ||
set optimizer_full_scan = off; | ||
--error ER_FULL_SCAN_DISABLED | ||
select * from t a, t b where a.i = b.i; | ||
set optimizer_full_scan = on; | ||
select * from t a, t b where a.i = b.i; | ||
|
||
--replace_column 9 # | ||
explain select * from t a straight_join t b where a.i = 10; | ||
set optimizer_full_scan = off; | ||
--error ER_FULL_SCAN_DISABLED | ||
select * from t a straight_join t b where a.i = 10; | ||
set optimizer_full_scan = on; | ||
select * from t a straight_join t b where a.i = 10; | ||
|
||
--echo # Test integration with optimizer_force_index_for_range | ||
alter table t drop index i, add primary key (i, j); | ||
|
||
--echo # Test range plans | ||
set optimizer_force_index_for_range = on; | ||
set optimizer_full_scan = off; | ||
--replace_column 9 # | ||
explain select i from t where i in (1, 2, 3) and j in (1, 2); | ||
--error ER_FULL_SCAN_DISABLED | ||
select i from t where i in (1, 2, 3) and j in (1, 2); | ||
--replace_column 9 # | ||
explain select i from t force index (primary) where i in (1, 2, 3) and j in (1, 2); | ||
select i from t force index (primary) where i in (1, 2, 3) and j in (1, 2); | ||
|
||
drop table t; | ||
|
||
set optimizer_full_scan = @orig_optimizer_full_scan; | ||
set optimizer_force_index_for_range = @orig_optimizer_force_index_for_range; | ||
|
Oops, something went wrong.