mysql:存储函数调用+左连接=非常慢

时间:2015-05-01 06:00:55

标签: mysql stored-functions

我有两张桌子:

module_339 (id,name,description,etc)
module_339_schedule(id,itemid,datestart,dateend,timestart,timeend,days,recurrent)
  

module_339_schedule.itemid指向module_339

     

拳头桌举行会议

     

第二个保留会议的时间表

     

module_339有3个项目

     

module_339_schedule有4000多个项目 - 几乎在3个会议之间分配

我有一个存储功能 - " getNextDate_module_339" - 这将计算"下一个日期"对于指定的会议,为了能够显示它,并根据它进行排序 - 如果用户想要的话。此存储过程将只获取指定会议的所有计划条目并循环显示它们,比较日期和时间。所以它会从module_339_schedule做一个简单的读取,然后遍历这些项目并比较日期和时间。

问题:此查询非常慢:

SELECT 
distinct(module_339.id)
,min( getNextDate_module_339(module_339.id,1,false)) AS ND 
FROM 
module_339 
LEFT JOIN module_339_schedule on module_339.id=module_339_schedule.itemid /* standard schedule adding */  
WHERE 1=1 AND module_339.is_system_preview<=0 
group by 
module_339.id  
order by 
module_339.id asc 

如果我删除了函数调用或LEFT JOIN,它再次快速。 我在这做错了什么?似乎是某种&#34;碰撞&#34;在函数调用和左连接之间。

2 个答案:

答案 0 :(得分:1)

我认为group by部分可以从此查询中删除,因此您也可以删除min功能。此外,WHERE 1=1 AND...没有多大意义,所以我也改变了这一点。 试试这个:

SELECT DISTINCT module_339.id
               ,getNextDate_module_339(module_339.id,1,false) AS ND 
FROM module_339 
LEFT JOIN module_339_schedule ON module_339.id=module_339_schedule.itemid /* standard schedule adding */  
WHERE module_339.is_system_preview<=0 
ORDER BY module_339.id

注意,这可能不会对性能产生太大影响 我认为性能最差的部分可能是getNextDate_module_339函数 如果你能找到一种方法来获得它的功能而不使用函数作为子查询,你的sql语句可能会比现在运行得更快,无论有没有左连接。
如果您需要帮助,请编辑您的问题以包含该功能,并希望我(或其他人)可以帮助您。

答案 1 :(得分:0)

从MySQL参考手册:

  

提高SELECT操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引条目的作用类似于表行的指针,允许查询快速确定哪些行与WHERE子句中的条件匹配,并检索这些行的其他列值。可以索引所有MySQL数据类型。

     

虽然为查询中使用的每个可能列创建索引很有吸引力,但不必要的索引会浪费空间并浪费时间让MySQL确定要使用的索引。索引还会增加插入,更新和删除的成本,因为必须更新每个索引。您必须找到适当的平衡,以使用最佳索引集实现快速查询。

作为第一步,我建议检查已连接的列是否已编入索引。由于主键始终默认为索引,因此我们可以假设module_339已在id列上编入索引,因此首先验证module_339_schedule是否已在itemid列上编入索引。您可以使用以下方法检查MySQL中该表的索引:

SHOW INDEX FROM module_339_schedule;

如果表中没有该列的索引,您可以使用以下命令添加:

CREATE INDEX itemid_index ON module_339_schedule (itemid);

这应该加快查询的连接组件。

由于您的查询还引用了module_339.is_system_preview,您还可以考虑使用以下方法向该列添加索引:

CREATE INDEX is_system_preview_index ON module_339 (is_system_preview);

您也可以优化存储过程,但未将其包含在您的问题中。

相关问题