mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +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:
@ -851,3 +851,257 @@ WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func5';
|
||||
SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE CREATED LAST_ALTERED SQL_MODE ROUTINE_COMMENT DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION
|
||||
test_func5 def i_s_routines_test test_func5 FUNCTION varchar 30 90 NULL NULL NULL utf8mb3 utf8mb3_general_ci varchar(30) SQL RETURN CONCAT('XYZ, ' ,s) NULL NULL SQL NO CONTAINS SQL NULL DEFINER <created> <modified> root@localhost latin1 latin1_swedish_ci utf8mb3_general_ci
|
||||
DROP DATABASE i_s_routines_test;
|
||||
#
|
||||
# MDEV-20609 Full table scan in INFORMATION_SCHEMA.PARAMETERS/ROUTINES
|
||||
#
|
||||
DROP DATABASE IF EXISTS i_s_routines_test;
|
||||
CREATE DATABASE i_s_routines_test;
|
||||
USE i_s_routines_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.ROUTINES
|
||||
WHERE CONCAT(ROUTINE_SCHEMA) = 'i_s_routines_test'
|
||||
AND ROUTINE_NAME = 'test_func5';
|
||||
SPECIFIC_NAME test_func5
|
||||
ROUTINE_CATALOG def
|
||||
ROUTINE_SCHEMA i_s_routines_test
|
||||
ROUTINE_NAME test_func5
|
||||
ROUTINE_TYPE FUNCTION
|
||||
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_BODY SQL
|
||||
ROUTINE_DEFINITION RETURN CONCAT('XYZ, ' ,s)
|
||||
EXTERNAL_NAME NULL
|
||||
EXTERNAL_LANGUAGE NULL
|
||||
PARAMETER_STYLE SQL
|
||||
IS_DETERMINISTIC NO
|
||||
SQL_DATA_ACCESS CONTAINS SQL
|
||||
SQL_PATH NULL
|
||||
SECURITY_TYPE DEFINER
|
||||
CREATED <created>
|
||||
LAST_ALTERED <modified>
|
||||
SQL_MODE
|
||||
ROUTINE_COMMENT
|
||||
DEFINER root@localhost
|
||||
CHARACTER_SET_CLIENT latin1
|
||||
COLLATION_CONNECTION latin1_swedish_ci
|
||||
DATABASE_COLLATION latin1_swedish_ci
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 54
|
||||
Handler_read_rnd_next 55
|
||||
#
|
||||
# Now the index must be used
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = 'i_s_routines_test'
|
||||
AND ROUTINE_NAME = 'test_func5';
|
||||
SPECIFIC_NAME test_func5
|
||||
ROUTINE_CATALOG def
|
||||
ROUTINE_SCHEMA i_s_routines_test
|
||||
ROUTINE_NAME test_func5
|
||||
ROUTINE_TYPE FUNCTION
|
||||
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_BODY SQL
|
||||
ROUTINE_DEFINITION RETURN CONCAT('XYZ, ' ,s)
|
||||
EXTERNAL_NAME NULL
|
||||
EXTERNAL_LANGUAGE NULL
|
||||
PARAMETER_STYLE SQL
|
||||
IS_DETERMINISTIC NO
|
||||
SQL_DATA_ACCESS CONTAINS SQL
|
||||
SQL_PATH NULL
|
||||
SECURITY_TYPE DEFINER
|
||||
CREATED <created>
|
||||
LAST_ALTERED <modified>
|
||||
SQL_MODE
|
||||
ROUTINE_COMMENT
|
||||
DEFINER root@localhost
|
||||
CHARACTER_SET_CLIENT latin1
|
||||
COLLATION_CONNECTION latin1_swedish_ci
|
||||
DATABASE_COLLATION latin1_swedish_ci
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 1
|
||||
Handler_read_rnd_next 2
|
||||
#
|
||||
# Using the first key part of the index
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = 'i_s_routines_test';
|
||||
SPECIFIC_NAME test_func5
|
||||
ROUTINE_CATALOG def
|
||||
ROUTINE_SCHEMA i_s_routines_test
|
||||
ROUTINE_NAME test_func5
|
||||
ROUTINE_TYPE FUNCTION
|
||||
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_BODY SQL
|
||||
ROUTINE_DEFINITION RETURN CONCAT('XYZ, ' ,s)
|
||||
EXTERNAL_NAME NULL
|
||||
EXTERNAL_LANGUAGE NULL
|
||||
PARAMETER_STYLE SQL
|
||||
IS_DETERMINISTIC NO
|
||||
SQL_DATA_ACCESS CONTAINS SQL
|
||||
SQL_PATH NULL
|
||||
SECURITY_TYPE DEFINER
|
||||
CREATED <created>
|
||||
LAST_ALTERED <modified>
|
||||
SQL_MODE
|
||||
ROUTINE_COMMENT
|
||||
DEFINER root@localhost
|
||||
CHARACTER_SET_CLIENT latin1
|
||||
COLLATION_CONNECTION latin1_swedish_ci
|
||||
DATABASE_COLLATION latin1_swedish_ci
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 1
|
||||
Handler_read_rnd_next 2
|
||||
#
|
||||
# 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.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = 'i_s_routines_test'
|
||||
AND ROUTINE_NAME = 'процедурка';
|
||||
SPECIFIC_NAME процедурка
|
||||
ROUTINE_CATALOG def
|
||||
ROUTINE_SCHEMA i_s_routines_test
|
||||
ROUTINE_NAME процедурка
|
||||
ROUTINE_TYPE PROCEDURE
|
||||
DATA_TYPE
|
||||
CHARACTER_MAXIMUM_LENGTH NULL
|
||||
CHARACTER_OCTET_LENGTH NULL
|
||||
NUMERIC_PRECISION NULL
|
||||
NUMERIC_SCALE NULL
|
||||
DATETIME_PRECISION NULL
|
||||
CHARACTER_SET_NAME NULL
|
||||
COLLATION_NAME NULL
|
||||
DTD_IDENTIFIER NULL
|
||||
ROUTINE_BODY SQL
|
||||
ROUTINE_DEFINITION SELECT a
|
||||
EXTERNAL_NAME NULL
|
||||
EXTERNAL_LANGUAGE NULL
|
||||
PARAMETER_STYLE SQL
|
||||
IS_DETERMINISTIC NO
|
||||
SQL_DATA_ACCESS CONTAINS SQL
|
||||
SQL_PATH NULL
|
||||
SECURITY_TYPE DEFINER
|
||||
CREATED <created>
|
||||
LAST_ALTERED <modified>
|
||||
SQL_MODE
|
||||
ROUTINE_COMMENT
|
||||
DEFINER root@localhost
|
||||
CHARACTER_SET_CLIENT koi8r
|
||||
COLLATION_CONNECTION koi8r_general_ci
|
||||
DATABASE_COLLATION latin1_swedish_ci
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
Variable_name Value
|
||||
Handler_read_next 1
|
||||
Handler_read_rnd_next 2
|
||||
#
|
||||
# Test SHOW PROCEDURE STATUS. It's impossible to use the index here
|
||||
# so don't check Handler_read counters, only the results correctness
|
||||
SHOW FUNCTION STATUS LIKE 'test_func5';
|
||||
Db i_s_routines_test
|
||||
Name test_func5
|
||||
Type FUNCTION
|
||||
Definer root@localhost
|
||||
Modified <modified>
|
||||
Created <created>
|
||||
Security_type DEFINER
|
||||
Comment
|
||||
character_set_client latin1
|
||||
collation_connection latin1_swedish_ci
|
||||
Database Collation latin1_swedish_ci
|
||||
SHOW FUNCTION STATUS LIKE 'test_%';
|
||||
Db i_s_routines_test
|
||||
Name test_func5
|
||||
Type FUNCTION
|
||||
Definer root@localhost
|
||||
Modified <modified>
|
||||
Created <created>
|
||||
Security_type DEFINER
|
||||
Comment
|
||||
character_set_client latin1
|
||||
collation_connection latin1_swedish_ci
|
||||
Database Collation latin1_swedish_ci
|
||||
SHOW FUNCTION STATUS LIKE '%func%';
|
||||
Db i_s_routines_test
|
||||
Name test_func5
|
||||
Type FUNCTION
|
||||
Definer root@localhost
|
||||
Modified <modified>
|
||||
Created <created>
|
||||
Security_type DEFINER
|
||||
Comment
|
||||
character_set_client latin1
|
||||
collation_connection latin1_swedish_ci
|
||||
Database Collation latin1_swedish_ci
|
||||
SHOW FUNCTION STATUS LIKE 'test';
|
||||
SHOW PROCEDURE STATUS LIKE 'процедурка';
|
||||
Db i_s_routines_test
|
||||
Name процедурка
|
||||
Type PROCEDURE
|
||||
Definer root@localhost
|
||||
Modified <modified>
|
||||
Created <created>
|
||||
Security_type DEFINER
|
||||
Comment
|
||||
character_set_client koi8r
|
||||
collation_connection koi8r_general_ci
|
||||
Database Collation latin1_swedish_ci
|
||||
SHOW PROCEDURE STATUS LIKE '%оцедурка';
|
||||
Db i_s_routines_test
|
||||
Name процедурка
|
||||
Type PROCEDURE
|
||||
Definer root@localhost
|
||||
Modified <modified>
|
||||
Created <created>
|
||||
Security_type DEFINER
|
||||
Comment
|
||||
character_set_client koi8r
|
||||
collation_connection koi8r_general_ci
|
||||
Database Collation latin1_swedish_ci
|
||||
SHOW PROCEDURE STATUS LIKE '%оцедур%';
|
||||
Db i_s_routines_test
|
||||
Name процедурка
|
||||
Type PROCEDURE
|
||||
Definer root@localhost
|
||||
Modified <modified>
|
||||
Created <created>
|
||||
Security_type DEFINER
|
||||
Comment
|
||||
character_set_client koi8r
|
||||
collation_connection koi8r_general_ci
|
||||
Database Collation latin1_swedish_ci
|
||||
SHOW PROCEDURE STATUS LIKE 'такой_нет';
|
||||
DROP DATABASE i_s_routines_test;
|
||||
USE test;
|
||||
|
Reference in New Issue
Block a user