mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-20609 Full table scan in INFORMATION_SCHEMA.PARAMETERS/ROUTINES
Queries to INFORMATION_SCHEMA.PARAMETERS and ROUTINES tables are always performed using full index scan of the mysql.proc primary key on fields (`db`,`name`,`type`). This can be done in a much more effective way if `db` and `name` field values can be derived from the WHERE statement, like here: SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'test' AND SPECIFIC_NAME = 'my_func' or here: SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='my_func'. In such cases index range scan may be employed instead of full index scan. This commit makes the server retrieve lookup field values from the SQL statement and perform index range scan instead of full index scan if possible.
This commit is contained in:
@@ -626,3 +626,168 @@ DTD_IDENTIFIER ROW
|
||||
ROUTINE_TYPE PROCEDURE
|
||||
-------- --------
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# MDEV-20609 Full table scan in INFORMATION_SCHEMA.PARAMETERS/ROUTINES
|
||||
#
|
||||
DROP DATABASE IF EXISTS i_s_parameters_test;
|
||||
CREATE DATABASE i_s_parameters_test;
|
||||
USE i_s_parameters_test;
|
||||
CREATE FUNCTION test_func5 (s CHAR(20)) RETURNS VARCHAR(30)
|
||||
RETURN CONCAT('XYZ, ' ,s);
|
||||
#
|
||||
# We cannot use the index due to CONCAT()
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE CONCAT(SPECIFIC_SCHEMA) = 'i_s_parameters_test'
|
||||
AND SPECIFIC_NAME = 'test_func5';
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME test_func5
|
||||
ORDINAL_POSITION 0
|
||||
PARAMETER_MODE NULL
|
||||
PARAMETER_NAME NULL
|
||||
DATA_TYPE varchar
|
||||
CHARACTER_MAXIMUM_LENGTH 30
|
||||
CHARACTER_OCTET_LENGTH 30
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME latin1
|
||||
COLLATION_NAME latin1_swedish_ci
|
||||
DTD_IDENTIFIER varchar(30)
|
||||
ROUTINE_TYPE FUNCTION
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME test_func5
|
||||
ORDINAL_POSITION 1
|
||||
PARAMETER_MODE IN
|
||||
PARAMETER_NAME s
|
||||
DATA_TYPE char
|
||||
CHARACTER_MAXIMUM_LENGTH 20
|
||||
CHARACTER_OCTET_LENGTH 20
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME latin1
|
||||
COLLATION_NAME latin1_swedish_ci
|
||||
DTD_IDENTIFIER char(20)
|
||||
ROUTINE_TYPE FUNCTION
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 54
|
||||
Handler_read_rnd_next 97
|
||||
#
|
||||
# Now the index must be used
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test'
|
||||
AND SPECIFIC_NAME = 'test_func5';
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME test_func5
|
||||
ORDINAL_POSITION 0
|
||||
PARAMETER_MODE NULL
|
||||
PARAMETER_NAME NULL
|
||||
DATA_TYPE varchar
|
||||
CHARACTER_MAXIMUM_LENGTH 30
|
||||
CHARACTER_OCTET_LENGTH 30
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME latin1
|
||||
COLLATION_NAME latin1_swedish_ci
|
||||
DTD_IDENTIFIER varchar(30)
|
||||
ROUTINE_TYPE FUNCTION
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME test_func5
|
||||
ORDINAL_POSITION 1
|
||||
PARAMETER_MODE IN
|
||||
PARAMETER_NAME s
|
||||
DATA_TYPE char
|
||||
CHARACTER_MAXIMUM_LENGTH 20
|
||||
CHARACTER_OCTET_LENGTH 20
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME latin1
|
||||
COLLATION_NAME latin1_swedish_ci
|
||||
DTD_IDENTIFIER char(20)
|
||||
ROUTINE_TYPE FUNCTION
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 1
|
||||
Handler_read_rnd_next 3
|
||||
#
|
||||
# Using the first key part of the index
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test';
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME test_func5
|
||||
ORDINAL_POSITION 0
|
||||
PARAMETER_MODE NULL
|
||||
PARAMETER_NAME NULL
|
||||
DATA_TYPE varchar
|
||||
CHARACTER_MAXIMUM_LENGTH 30
|
||||
CHARACTER_OCTET_LENGTH 30
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME latin1
|
||||
COLLATION_NAME latin1_swedish_ci
|
||||
DTD_IDENTIFIER varchar(30)
|
||||
ROUTINE_TYPE FUNCTION
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME test_func5
|
||||
ORDINAL_POSITION 1
|
||||
PARAMETER_MODE IN
|
||||
PARAMETER_NAME s
|
||||
DATA_TYPE char
|
||||
CHARACTER_MAXIMUM_LENGTH 20
|
||||
CHARACTER_OCTET_LENGTH 20
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME latin1
|
||||
COLLATION_NAME latin1_swedish_ci
|
||||
DTD_IDENTIFIER char(20)
|
||||
ROUTINE_TYPE FUNCTION
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 1
|
||||
Handler_read_rnd_next 3
|
||||
#
|
||||
# Test non-latin letters in procedure name
|
||||
SET NAMES koi8r;
|
||||
CREATE PROCEDURE `процедурка`(a INT) SELECT a;
|
||||
#
|
||||
# The index must be used
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test'
|
||||
AND SPECIFIC_NAME = 'процедурка';
|
||||
SPECIFIC_CATALOG def
|
||||
SPECIFIC_SCHEMA i_s_parameters_test
|
||||
SPECIFIC_NAME процедурка
|
||||
ORDINAL_POSITION 1
|
||||
PARAMETER_MODE IN
|
||||
PARAMETER_NAME a
|
||||
DATA_TYPE int
|
||||
CHARACTER_MAXIMUM_LENGTH NULL
|
||||
CHARACTER_OCTET_LENGTH NULL
|
||||
NUMERIC_PRECISION 10
|
||||
NUMERIC_SCALE 0
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME NULL
|
||||
COLLATION_NAME NULL
|
||||
DTD_IDENTIFIER int(11)
|
||||
ROUTINE_TYPE PROCEDURE
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 1
|
||||
Handler_read_rnd_next 2
|
||||
DROP DATABASE i_s_parameters_test;
|
||||
USE test;
|
||||
|
Reference in New Issue
Block a user