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:
@@ -249,3 +249,79 @@ WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func5';
|
||||
|
||||
# final clean up
|
||||
DROP DATABASE i_s_routines_test;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-20609 Full table scan in INFORMATION_SCHEMA.PARAMETERS/ROUTINES
|
||||
--echo #
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS i_s_routines_test;
|
||||
--enable_warnings
|
||||
|
||||
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);
|
||||
|
||||
--echo #
|
||||
--echo # We cannot use the index due to CONCAT()
|
||||
FLUSH STATUS;
|
||||
--replace_column 24 <created> 25 <modified>
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE CONCAT(ROUTINE_SCHEMA) = 'i_s_routines_test'
|
||||
AND ROUTINE_NAME = 'test_func5';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
--echo #
|
||||
--echo # Now the index must be used
|
||||
FLUSH STATUS;
|
||||
--replace_column 24 <created> 25 <modified>
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = 'i_s_routines_test'
|
||||
AND ROUTINE_NAME = 'test_func5';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
--echo #
|
||||
--echo # Using the first key part of the index
|
||||
FLUSH STATUS;
|
||||
--replace_column 24 <created> 25 <modified>
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = 'i_s_routines_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;
|
||||
--replace_column 24 <created> 25 <modified>
|
||||
query_vertical SELECT * FROM INFORMATION_SCHEMA.ROUTINES
|
||||
WHERE ROUTINE_SCHEMA = 'i_s_routines_test'
|
||||
AND ROUTINE_NAME = 'процедурка';
|
||||
SHOW STATUS LIKE 'handler_read%next';
|
||||
|
||||
--echo #
|
||||
--echo # Test SHOW PROCEDURE STATUS. It's impossible to use the index here
|
||||
--echo # so don't check Handler_read counters, only the results correctness
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW FUNCTION STATUS LIKE 'test_func5';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW FUNCTION STATUS LIKE 'test_%';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW FUNCTION STATUS LIKE '%func%';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW FUNCTION STATUS LIKE 'test';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW PROCEDURE STATUS LIKE 'процедурка';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW PROCEDURE STATUS LIKE '%оцедурка';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW PROCEDURE STATUS LIKE '%оцедур%';
|
||||
--replace_column 5 <modified> 6 <created>
|
||||
query_vertical SHOW PROCEDURE STATUS LIKE 'такой_нет';
|
||||
|
||||
# Cleanup
|
||||
DROP DATABASE i_s_routines_test;
|
||||
USE test;
|
||||
|
Reference in New Issue
Block a user