为什么这个存储过程:
CREATE
DEFINER = mysql_user@`%` PROCEDURE sp_GetSessionData(IN SessionId varchar(45))
BEGIN
SELECT * FROM sessiondata WHERE SessionGuid = SessionId;
END;
需要 5 分钟才能运行,但这个等效查询:
SELECT * FROM sessiondata WHERE SessionGuid = 'd2c26d6d-4e80-4e80-4e80-2d7ca9cfa3a3';
运行仅需40ms?
我在 SessionGuid
列上有一个索引,并且该列的类型为 varchar(45)
,它与我的存储过程的输入参数完全相同。
更新:
以下是将 EXPLAIN
放入存储过程中时得到的结果:
╔════╦═════════════╦══════════╦════════════╦══════╦═══════════════╦══════╦═════════╦══════╦══════════╦══════════╦═════════════╗
║ id ║ select_type ║ table ║ partitions ║ type ║ possible_keys ║ key ║ key_len ║ ref ║ rows ║ filtered ║ Extra ║
╠════╬═════════════╬══════════╬════════════╬══════╬═══════════════╬══════╬═════════╬══════╬══════════╬══════════╬═════════════╣
║ 1 ║ SIMPLE ║ perfinfo ║ NULL ║ ALL ║ NULL ║ NULL ║ NULL ║ NULL ║ 77249445 ║ 100 ║ Using where ║
╚════╩═════════════╩══════════╩════════════╩══════╩═══════════════╩══════╩═════════╩══════╩══════════╩══════════╩═════════════╝
这是 sessiondata
表的EXPLAIN
:
╔═════════════════╦══════════════════╦══════╦═════╦═════════╦════════════════╗
║ Field ║ Type ║ Null ║ Key ║ Default ║ Extra ║
╠═════════════════╬══════════════════╬══════╬═════╬═════════╬════════════════╣
║ PerfId ║ int(11) unsigned ║ NO ║ PRI ║ NULL ║ auto_increment ║
║ SessionGuid ║ varchar(45) ║ NO ║ MUL ║ NULL ║ ║
║ BuildId ║ int(11) ║ NO ║ MUL ║ NULL ║ ║
║ Metric ║ float ║ NO ║ ║ NULL ║ ║
║ MetricId ║ int(11) unsigned ║ NO ║ MUL ║ NULL ║ ║
║ Location ║ varchar(45) ║ NO ║ ║ NULL ║ ║
║ RunTypeId ║ int(11) ║ NO ║ ║ NULL ║ ║
║ MetaContextId ║ int(11) ║ NO ║ MUL ║ -1 ║ ║
║ SecondsFromBoot ║ int(10) unsigned ║ NO ║ ║ NULL ║ ║
║ Timestamp ║ datetime ║ NO ║ ║ NULL ║ ║
║ DeviceId ║ int(11) ║ NO ║ MUL ║ -1 ║ ║
╚═════════════════╩══════════════════╩══════╩═════╩═════════╩════════════════╝
最佳答案
要查看字符集/排序规则的差异是否导致 sp 查询不使用索引,请查看设置中是否存在差异:
要查看列上的信息:
select CHARACTER_SET_NAME, COLLATION_NAME
from information_schema.COLUMNS
where TABLE_SCHEMA='*YOURDATABASENAME*'
and TABLE_NAME='sessiondata' and COLUMN_NAME='SessionGuid';
查看 sp 参数的信息:
select CHARACTER_SET_NAME, COLLATION_NAME
from information_schema.PARAMETERS
where SPECIFIC_SCHEMA='*YOURDATABASENAME*'
and SPECIFIC_NAME='sp_GetSessionData' and PARAMETER_NAME='SessionId';
最后是连接详细信息:
show variables where variable_name like 'character_set%'
or variable_name like '%collation%';
理想情况下,SessionGuid
的字符集可以设置为 'ascii'
,这样缓存中可以容纳更多值。
关于mysql - 存储过程比等效查询慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57998640/