什么是更快:在查询中调用用户声明的函数或通过触发器设置值?

时间:2015-08-17 12:05:14

标签: mysql query-optimization

声明的MySQL函数GETUSERID()返回一个整数值。如何使记录插入更快:从像

这样的查询中设置值
INSERT INTO ttable 
(idtoset, some_other_field...) 
VALUES (GETUSERID(), value1...);

或致电

INSERT INTO ttable 
(some_other_field...) 
VALUES (value1...);

并通过在插入之前触发的触发器填充idtoset

如果查询正在执行多行插入,如

,该怎么办?
INSERT INTO ttable 
(idtoset, some_other_field...) 
VALUES (GETUSERID(), value1...), 
(GETUSERID(), value2...),
... 
(GETUSERID(), valueN...);

修改

我刚刚调查了@Rahul的答案。 我创建了一个带有两个触发器的ttest表

CREATE TRIGGER `tgbi` BEFORE INSERT ON `ttest` FOR EACH ROW BEGIN
SET NEW.testint=1;
END;

CREATE TRIGGER `tgbi` BEFORE UPDATE ON `ttest` FOR EACH ROW BEGIN
SET NEW.testint=2;
END;

如果我没有弄错,那么在插入触发器调用UPDATE SET之前,第二个触发器是否也应该触发,并且创建的testint值可能是= 2,但在每个插入的行中它是= 1。这是否意味着引擎优化INSERT过程并通过查询手动设置该值?

根据@ Rick-James的要求

附加。问题不在于确定的功能。它实际上是关于任何功能。如果从触发器或INSERT查询插入记录,则任何函数都将被调用相同的次数。这就是为什么我想知道从MySQL引擎的角度来看哪个更好 - 手动设置插入记录中的值或通过触发器填充它?

CREATE DEFINER=`***`@`***` FUNCTION `GETUSERID`() RETURNS int(10)
BEGIN
DECLARE id_no INT DEFAULT -1;
SELECT `id` INTO id_no FROM `tstuff` 
WHERE `tstuff`.`user_name`=
(SELECT SUBSTRING_INDEX(USER(), '@', 1)) LIMIT 1;
RETURN id_no;
END

2 个答案:

答案 0 :(得分:2)

什么更快?不知道,因为我还没有做过基准测试,但是直接INSERT操作会更好地根据我的知识而不是插入然后执行UPDATE通过触发器。

你现在正在做什么不工作?您也可以将其作为INSERT .. SELECT操作,如

INSERT INTO ttable (idtoset, some_other_field...) 
SELECT GETUSERID(), value1..., valuen FROM DUAL;

答案 1 :(得分:1)

在过去的MySQL版本中,使用before insert触发器填充不可为空的列并不起作用,因为MySQL在触发器之前评估提供的列。这就是为什么每当我遇到这种情况时,我通常倾向于使用函数而不是触发器。

从性能的角度来看,由于在实际写入数据之前评估了insert插入触发器,因此执行此操作所需的时间几乎与使用函数立即获取值并且没有触发器的时间相同。但如果您在触发器中所做的只是设置了用户ID,那么我真的认为没有理由使用触发器。