我有一个包含userID,department,er的表。我创建了一个简单的查询来收集所有这些信息。
SELECT table.userID, table.department, table.er FROM table;
现在,我想对属于同一部门的所有人进行分组并执行此计算
select sum(table.er)/3 as department_er from table group by table.department;
然后在第一个查询中将此结果添加为新列。为此,我创建了一个看起来像这样的UDF
BEGIN
DECLARE department_er FLOAT;
set department_er = (select sum(er) from table where table.department = dpt);
RETURN department_er;
END
然后我在此查询中使用了该UDF
SELECT table.userID, table.department, (select dptER(table.department)/3) as department_er FROM table
我已将我的表编入索引,更复杂的查询从4分钟以上删除到不到1秒。这似乎很简单,但运行10分钟。有没有更好的方法来实现这一点或优化我的UDF?
原谅我的n00b-ness:)
答案 0 :(得分:1)
在SELECT子句中尝试不带依赖聚合子查询的查询:
select table.userID,
table.department as dpt,
x.department_er
from table
join (
select department,
(sum(table.er)/3) As department_er
from table
group by department
) x
ON x.department = table.department
无法优化此UDF功能。也许它似乎适用于简单的查询,但通常它会损害您的数据库性能。
想象一下,我们有一个像这样的查询:
SELECT ....., UDF( some parameters )
FROM table
....
MySql必须为从此查询中的表中检索到的每条记录调用此函数
如果表包含1000条记录 - 该函数将被触发1000次。
并且函数内的查询也会被触发1000次。
如果是10.000记录 - 那么该函数被称为10.000次。
即使您以这种方式优化此功能,UDF将快2倍,上述查询仍将触发该功能1000次。
如果500个用户拥有相同的部门 - 每个用户仍然会调用500次,并为每个用户计算相同的值。 499次冗余通话,因为只需1次通话即可计算此值。
优化此类查询的唯一方法是采用"内部"从UDF函数中查询并使用连接等将其与主查询相结合。