mysql - 存储过程比等效查询慢

标签 mysql

为什么这个存储过程:

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/

相关文章:

MySQL 多个复制用户

PHP/MySQL - 为每个用户在 1 个表中计算 2 个不同的总数

php - 使用 PHP 将数据从表单插入 MySQL 数据库

php - 从给定数组中 id 的数据库中选择

sql - MySQL 从临时表返回单行

php - 去掉逗号分隔值

mysql - rake 数据库 :create error with mysql2 gem (Couldn't create database for {"adapter"= >"mysql2")

php - 无法更新mysql表

mysql - SQL:给定某些元素的精确行匹配

php - IIS + PHP + MySQL 返回 500 - 内部服务器错误