1
0
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:
Oleg Smirnov
2022-09-12 14:28:00 +07:00
parent 9206c1ea97
commit beb9a5459d
5 changed files with 638 additions and 38 deletions

View File

@ -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;