在查询中混合使用过程化和关系化逻辑的时候,自定义变量可能会非常有用。单纯的关系查询将所有的东西都当成无序的数据集合,并且一次性操作它们。
用户自定义变量是一个用来存储内容的临时容器,在连接MySQL的整个过程中都存在。可以使用SET和SELECT来定义他们(在某些情况下,也可以使用=来赋值,不过为了避免歧义,建议始终使用:=):
SET @one := 1;
SET @min_actor := (SELECT MIN(actor_id) FROM actor);
SET @last_week := CURRENT_DATE-INTERVAL 1 WEEK;
然后可以在任何使用表达式的地方使用这些自定义变量:
select ... where col <= @last_week;

自定义变量的属性和限制

  • 使用自定义变量的查询,无法使用查询缓存。
  • 不能在使用常量或者标识列的地方使用自定义变量,例如表名、列明和LIMIT子句中。
  • 用户自定义变量的生命周期是在一个连接中有效,所以不能使用它们来做连接间的通信。
  • 如果使用连接池或者持久化连接,自定义变量可能让看起来毫无关系的代码发生交互。
  • 在5.0版本之前,是大小写敏感的,所以要注意代码在不同版本之间的兼容性问题。
  • 不能显示的声明自定义变量的类型。它是一个动态类型。整数初始化为0,浮点型初始化为0.0,字符串初始化为’’。
  • MySQL优化器在某些场景下可能会将这些变量优化掉,这可能导致代码不按预想的方式运行。
  • 赋值的顺序和赋值的时间点并不总是固定的,这依赖于优化器的决定。
  • 赋值符号:=的优先级非常低,所有要注意赋值表达式应该使用明确的括号。
  • 使用未定义变量不会产生任何错误,如果没有意识到这一点,非常容易犯错。

优化排名语句

  • 自定义变量的一个重要的特性是可以在给一个赋值的同时使用这个变量。换句话说,用户自定义变量具有“左值特性”,如下:
mysql> SET @rownum := 0;
mysql> SELECT actor_id, @rownum := @rownum + 1 AS rownum FROM actor LIMIT 3;
  • 在使用用户自定义变量的时候,经常会遇到一些"诡异"的现象,我们应该深究这些问题。通过检查是否变量名拼写错误,或者通过EXPLAIN看是否使用了临时表或文件排序,则表示可能是变量的赋值时间和我们预想的不同。
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐