mlu*_*udd 10 mysql sql stored-procedures
我一直试图弄清楚我得到的一系列查询有什么问题,而我现在只是感到困惑.
它应该在一个存储过程中,由GUI应用程序调用.
只有一个"微小"的问题,它首先是一个简单的问题UPDATE,然后是一个INSERT使用SELECT带有子选择的问题,最后是另一个问题UPDATE.手动运行这些查询我得到的总执行时间为0.057秒,而不是太破旧.
现在,我尝试使用这些查询创建一个存储过程和五个输入变量,我运行此过程并在第一次尝试时花了47.096s,随后调用它显示类似的执行时间(35到50秒).从MySQL Workbench运行各个查询仍然显示执行时间小于0.1秒
这些查询确实没有什么花哨的东西,那么为什么存储过程需要永久执行而查询本身只需要几分之一秒?我在这里缺少什么样的MySQL特性吗?
其他测试结果:
似乎如果我在MySQL Workbench中运行查询但是使用变量而不是仅仅将变量的值放在查询中它运行的速度和存储过程一样慢.因此,我尝试将存储过程更改为仅使用静态值而不是变量,突然间它的速度非常快.显然,使用一个变量使得它运行非常缓慢(例如,第一某种原因UPDATE查询从三个变量,大约需要0.98s去,当我用变量的值直接在查询中,不论它是在以0.04-0.05s存储过程或直接运行查询).
所以,问题不在于存储过程,而是与我使用变量有关(这是不可避免的).
我有同样的问题.经过一段时间的研究,我发现问题是整理问题,而MySQL正在比较文本.
TL; DR:表是在一个排序规则中创建的,而MySQL"认为"变量是在另一个排序规则中.因此,MySQL无法使用用于查询的索引.
在我的例子中,该表是使用(latin1,latin1_swedish_ci)排序规则创建的.为了使MySQL使用索引,我不得不更改where存储过程中的子句
UPDATE ... WHERE mycolumn = myvariable
Run Code Online (Sandbox Code Playgroud)
至
UPDATE ... WHERE mycolumn =
convert(myvariable using latin1) collate latin1_swedish_ci
Run Code Online (Sandbox Code Playgroud)
更改后,存储过程看起来像这样:
CREATE PROCEDURE foo.'bar'()
BEGIN
UPDATE mytable SET mycolumn1 = variable1
WHERE mycolumn2 =
convert(variable2 using latin1) collate latin1_swedish_ci
END;
Run Code Online (Sandbox Code Playgroud)
其中(latin1,latin1_swedish_ci)与我的tableA创建的排序规则相同.
要检查MySQL是否使用索引,您可以更改存储过程以运行explain语句,如下所示:
CREATE PROCEDURE foo.'bar'()
BEGIN
EXPLAIN SELECT * FROM table WHERE mycolumn2 = variable2
END;
Run Code Online (Sandbox Code Playgroud)
在我的例子中,explain结果显示在执行查询期间没有使用索引.
请注意,当您单独运行查询时,MySQL可能会使用索引,但仍然不会在存储过程中使用相同查询的索引,这可能是因为MySQL以某种方式在另一个排序规则中看到该变量.
在整理问题的更多信息可以在这里找到: http://lowleveldesign.wordpress.com/2013/07/19/diagnosing-collation-issue-mysql-stored-procedure/ 备份链接: HTTP://www.codeproject .COM /用品/ 623272 /诊断-A-比对问题-IN-A-MySQL的存储-PRO
我有一个类似的问题。运行 mysql 例程非常慢。但是一位同事帮助了我。问题是 AUTOCOMMIT 是真的;所以每次插入和选择都在创建一个完整的事务。然后我运行我的例程
SET autocommit=0;
Run Code Online (Sandbox Code Playgroud)
在开始和
SET autocommit=1;
Run Code Online (Sandbox Code Playgroud)
在末尾。性能从近 500 秒变为 4 秒