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:
@ -276,3 +276,56 @@ DELIMITER ;$$
|
||||
SELECT *, '--------' FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME = 'p1';
|
||||
--horizontal_results
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-20609 Full table scan in INFORMATION_SCHEMA.PARAMETERS/ROUTINES
|
||||
--echo #
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS i_s_parameters_test;
|
||||
--enable_warnings
|
||||
|
||||
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);
|
||||
|
||||
--echo #
|
||||
--echo # We cannot use the index due to CONCAT()
|
||||
FLUSH STATUS;
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE CONCAT(SPECIFIC_SCHEMA) = 'i_s_parameters_test'
|
||||
AND SPECIFIC_NAME = 'test_func5';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
--echo #
|
||||
--echo # Now the index must be used
|
||||
FLUSH STATUS;
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test'
|
||||
AND SPECIFIC_NAME = 'test_func5';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
--echo #
|
||||
--echo # Using the first key part of the index
|
||||
FLUSH STATUS;
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
--echo #
|
||||
--echo # Test non-latin letters in procedure name
|
||||
SET NAMES koi8r;
|
||||
CREATE PROCEDURE `процедурка`(a INT) SELECT a;
|
||||
--echo #
|
||||
--echo # The index must be used
|
||||
FLUSH STATUS;
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.PARAMETERS
|
||||
WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test'
|
||||
AND SPECIFIC_NAME = 'процедурка';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
# Cleanup
|
||||
DROP DATABASE i_s_parameters_test;
|
||||
USE test;
|
||||
|
Reference in New Issue
Block a user