Server System Variables(系统变量)

MySQL系统变量(system variables)是指MySQL实例的各种系统变量,实际上是一些系统参数,用于初始化或设定数据库对系统资源的占用,文件存放位置等等,这些变量包含MySQL编译时的参数默认值,或者my.cnf配置文件里配置的参数值。默认情况下系统变量都是小写字母。

作用域范围

系统变量(system variables)按作用域范围可以分为会话级别系统变量和全局级别系统变量。如果要确认系统变量是全局级别还是会话级别,如果Scope其值为GLOBAL或SESSION,表示变量既是全局级别系统变量,又是会话级别系统变量。如果其Scope其值为GLOBAL,表示系统变量为全局级别系统变量。

系统级别

查看系统变量的全局值

select * from information_schema.global_variables;

select * from information_schema.global_variables

where variable_name='xx';

select * from performance_schema.global_variables;

会话级别

查看系统变量的当前会话值

select * from information_schema.session_variables;

select * from information_schema.session_variables  where variable_name='xxxx';

select * from performance_schema.session_variables;

区分变量和操作变量

SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;

mysql> show variables like '%connect_timeout%';

mysql> show local variables like '%connect_timeout%';

mysql> show session variables like '%connect_timeout%';

mysql> show global variables like '%connect_timeout%';

注意:对于SHOW VARIABLES,如果不指定GLOBAL、SESSION或者LOCAL,MySQL返回SESSION值。

如果某一个系统变量是全局级别的,那么在当前会话的值也就是全局级别的值。例如系统变量AUTOMATIC_SP_PRIVILEGES,它是一个全局级别系统变量,但是 show session variables like '%automatic_sp_privileges%'一样能查到其值。

如果要区分系统变量是全局还是会话级别,可以用下面方式:

方法1: 查官方文档中系统变量的Scope属性。

方法2: 使用SET VARIABLE_NAME=xxx; 如果报ERROR 1229 (HY000),则表示该变量为全局,如果不报错,那么证明该系统变量为全局和会话两个级别。

修改全局级别系统变量

SET GLOBAL max_connections=300;

SET @@global.max_connections=300;

注意:更改全局变量的值,需要拥有SUPER权限

修改会话级别系统变量

SET @@session.max_join_size=DEFAULT;

SET max_join_size=DEFAULT;  --默认为会话变量。如果在变量名前没有级别限定符,表示修改会话级变量。

SET SESSION max_join_size=DEFAULT;

如果修改系统全局变量没有指定GLOBAL或@@global的话,就会报“Variable 'xxx' is a GLOBAL variable and should be set with SET GLOBAL”这类错误。

动态变量静态变量

系统变量(system variables)按是否可以动态修改,可以分为系统动态变量(Dynamic System Variables)和系统静态变量。怎么区分系统变量是动态和静态的呢? 这个只能查看官方文档,系统变量的"Dynamic"属性为Yes,则表示可以动态修改。

有些系统变量是只读的,不能修改的。如下所示:

mysql> set global innodb_version='5.6.21';

ERROR 1238 (HY000): Variable 'innodb_version' is a read only variable

Server Status Variables(服务器状态变量)

MySQL状态变量(Server Status Variables)是当前服务器从启动后累计的一些系统状态信息,例如最大连接数,累计的中断连接等等,主要用于评估当前系统资源的使用情况以进一步分析系统性能而做出相应的调整决策。状态变量是动态变化的。

状态变量是只读的:只能由MySQL服务器本身设置和修改,对于用户来说是只读的,不可以通过SET语句设置和修改它们,而系统变量则可以随时修改。

状态变量也分为会话级与全局级别状态信息。

有些状态变量可以用FLUSH STATUS语句重置为零值。

查看状态变量

关于查看状态变量,show status也支持like匹配查询。如下所示:

show status like '%variable_name%'

show global status like '%variable_name%'

#当前测试环境

mysql> select version() from dual;

mysql> show status;  --查看所有的状态变量

mysql> show global status like 'Aborted_connects%';

mysql> show session status like 'Aborted_connects%';

mysql> select * from information_schema.global_status;

ERROR 3167 (HY000): The 'INFORMATION_SCHEMA.GLOBAL_STATUS' feature is disabled; see the documentation for 'show_compatibility_56'

mysql> show variables like '%show_compatibility_56%';

查出来是flase。

mysql> set global show_compatibility_56=on;

mysql> select * from information_schema.global_status;

这样就可以查询了。

select * from performance_schema.global_status;

select * from performance_schema.session_status;

注意:MySQL 5.7以后系统变量和状态变量需要从performance_schema中进行获取,information_schema仍然保留了GLOBAL_STATUS,GLOBAL_VARIABLES两个表做兼容,如果希望沿用information_schema中进行查询的习惯,5.7提供了show_compatibility_56参数,设置为ON可以兼容5.7之前的用法,否则就会报错(ERROR 3167 (HY000)).

User-Defined Variables(用户自定义变量)

用户自定义变量就是用户自己定义的变量。

用户自定义变量是基于当前会话的。 也就是说用户自定义变量的作用域局限于当前会话(连接),由一个客户端定义的用户自定义变量不能被其他客户端看到或使用。

例外:可以访问performance_schema.user_variables_by_thread表的用户可以看到所有会话的定义的用户自定义变量,当然仅仅能看到那些会话定义了哪些变量,而不能访问这些变量。

当客户端会话退出时,当前会话所有的自定义变量都会自动释放。

一般可以在SQL语句将值存储在用户自定义变量中,然后再利用另一条SQL语句来查询用户自定义变量。这样以来,可以在不同的SQL间传递值。

用户自定义变量是大小写不敏感的,最大长度为64个字符,用户自定义变量的形式一般为@var_name,其中变量名称由字母、数字、“.”、“_”和“$”组成。当然,在以字符串或者标识符引用时也可以包含其他特殊字符(例如:@'my-var',@"my-var",或者@`my-var`)。。使用SET设置变量时,可以使用“=”或者“:=”操作符进行赋值。对于SET,可以使用=或:=来赋值,对于SELECT只能使用:=来赋值。

如下所示:

mysql> set @$test1="test";

mysql> select @$test1 from dual;

mysql> select connection_id() from dual;   返回当前连接id。149379

mysql> SELECT c.id,  b.thread_id FROM   performance_schema.threads b  join information_schema.processlist c ON b.processlist_id = c.id where c.id=149379;

+--------+-----------+

| id     | thread_id |

+--------+-----------+

| 149379 |    149404 |

+--------+-----------+

1 row in set (0.00 sec)

mysql> select * from performance_schema.user_variables_by_thread;

+-----------+---------------+----------------+

| THREAD_ID | VARIABLE_NAME | VARIABLE_VALUE |

+-----------+---------------+----------------+

|    149404 | my_test       | 1200           |

+-----------+---------------+----------------+

1 row in set (0.00 sec)

用户自定义变量注意事项,以下为总结:

1:未定义的用户自定义变量初始值是NULL

mysql> select @kerry from dual;

注意:使用未定义变量不会产生任何语法错误,由于其被初始化为NULL值,如果没有意识到这一点,非常容易犯错。

如下所示:

mysql> select @num1, @num2 :=@num1+1 from dual;

+-------+-----------------+

| @num1 | @num2 :=@num1+1 |

+-------+-----------------+

| NULL  |            NULL |

+-------+-----------------+

2:用户变量名对大小写不敏感。

3:自定义变量的类型是一个动态类型。MySQL中用户自定义变量,不严格限制数据类型的,它的数据类型根据你赋给它的值而随时变化。而且自定义变量如果赋予数字值,是不能保证进度的。

4:赋值的顺序和赋值的时间点并不总是固定的,这依赖于优化器的决定。

使用用户自定义变量的一个最常见的问题就是没有注意到在赋值和读取用户自定义变量的时候可能是在查询的不同阶段。

例如,在SELECT语句中进行赋值然后再WHERE子句中读取用户自定义变量,则可能用户自定义变量取值并不不是你所想象的那样。

如下例子所示,因为按照MySQL语句的执行顺序,WHERE部分优先与SELECT部分操作,所以你会看到msgid 和 @rownum的最大值为6.

mysql> select msgid from message order by msgid limit 12;

+-------+

| msgid |

+-------+

|     1 |

|     2 |

|     3 |

|     4 |

|     5 |

|     6 |

|     7 |

|    11 |

|    12 |

|    13 |

|    18 |

|    19 |

+-------+

12 rows in set (0.00 sec)

mysql> set @rownum := 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select msgid , @rownum := @rownum +1 as rownum from message where @rownum <=5;

+-------+--------+

| msgid | rownum |

+-------+--------+

|     1 |      1 |

|     2 |      2 |

|     3 |      3 |

|     4 |      4 |

|     5 |      5 |

|     6 |      6 |

+-------+--------+

6 rows in set (0.00 sec)

mysql> select msgid , @rownum := @rownum +1 as rownum from messagewhere @rownum <=5;

Empty set (0.00 sec)

mysql> select @rownum from dual;

+---------+

| @rownum |

+---------+

|       6 |

+---------+

1 row in set (0.00 sec)

如上所示,第二次查询可能你想要的逻辑跟实际逻辑已经出现了偏差,这个是使用自定义变量需要小心的地方。因为用户自定义变量在当前会话中也算一个“全局变量”,它已经变成了6,where条件后面的 @rownum <= 5 逻辑为false了。一不小小心就会出现和你预想的结果出现偏差。

不要在同一个非SET语句中同时赋值并使用同一个用户自定义变量,因为WHERE和SELECT是在查询执行的不同阶段被执行的。

如果在查询中再加入ORDER BY的话,结果可能会更不同;

mysql> set @rownum :=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select msgid , @rownum := @rownum +1 as rownum from message where @rownum <=5;

+-------+--------+

| msgid | rownum |

+-------+--------+

|     1 |      1 |

|     2 |      2 |

|     3 |      3 |

|     4 |      4 |

|     5 |      5 |

|     6 |      6 |

+-------+--------+

6 rows in set (0.00 sec)

mysql> set @rownum := 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select msgid, @rownum := @rownum +1 as rownum from message where @rownum <=5 order by msgcontent;

+-------+--------+

| msgid | rownum |

+-------+--------+

|    20 |      1 |

|    28 |      2 |

|    43 |      3 |

|    47 |      4 |

..................

..................

|    66 |     62 |

|    51 |     63 |

+-------+--------+

63 rows in set (0.00 sec)

如果按msgid排序,那么又是正常的,那三者有啥区别呢?

mysql> set @rownum :=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select msgid, @rownum := @rownum +1 as rownum from message where @rownum <=5 order by msgid;

+-------+--------+

| msgid | rownum |

+-------+--------+

|     1 |      1 |

|     2 |      2 |

|     3 |      3 |

|     4 |      4 |

|     5 |      5 |

|     6 |      6 |

+-------+--------+

6 rows in set (0.00 sec)

官方的解释如下:

在SELECT语句中,每个选择表达式仅在发送给客户端时才被计算。 这意味着在HAVING,GROUP BY或ORDER BY子句中,引用在选择表达式列表中指定值的用户自定义变量不能按预期工作。 也就是说用户自定义变量的值是在结果集发送到客户端后才计算的

关于用户自定义变量,如果运用的好,能够写出高效简洁的SQL语句,如果运用不当,也可能把自己给坑了。这个完全取决于使用它的人。

局部变量

局部变量:作用范围在begin到end语句块之间。在该语句块里设置的变量。

declare语句专门用于定义声明局部变量。

局部变量与用户自定义变量的区分在于下面这些方面:

  • 用户自定义变量是以"@"开头的。局部变量没有这个符号。
  • 定义变量方式不同。用户自定义变量使用set语句,局部变量使用declare语句定义
  • 作用范围不同。局部变量只在begin-end语句块之间有效。在begin-end语句块运行完之后,局部变量就消失了。而用户自定义变量是对当前连接(会话)有效。

Mysql的变量一览的更多相关文章

  1. Mysql 声明变量

    Mysql 声明变量 Mysql中声明变量有两种方式 第一种: set @num=1; 或set @num:=1; //这里要使用变量来保存数据,直接使用@num变量 第二种: select @num ...

  2. OS 系统下安装MySql 配置MySql环境变量

    学习Hive需要,闲话不说 本文的内容: 下载Mysql for Mac 下载Mysql Workbench 安装 Mysql 和 Mysql Workbench 配置Mysql在OS 系统上的环境变 ...

  3. mysql中变量赋值

    http://www.cnblogs.com/qixuejia/archive/2010/12/21/1913203.html sql server中变量要先申明后赋值: 局部变量用一个@标识,全局变 ...

  4. MySql 申明变量以及赋值

    sql server中变量要先申明后赋值: 局部变量用一个@标识,全局变量用两个@(常用的全局变量一般都是已经定义好的): 申明局部变量语法:declare @变量名 数据类型:例如:declare ...

  5. Mysql 的变量

    变量 MySQL是一门编程语言.所以存在变量.流程控制.函数.存储过程.触发器 MySQL分系统变量,与自定义变量 MySQL的某些功能是通过系统变量来实现的.例如:autocommit 查看系统变量 ...

  6. windows下如何设置mysql环境变量

    方法一: windows下如何设置mysql环境变量 关键词: mysql, Setting Environment Variables, 环境变量设置 我的电脑->属性->高级-> ...

  7. MySQL 服务器变量 数据操作DML-视图

    原文:MySQL 服务器变量 数据操作DML-视图 SQL语言的组成部分 常见分类: DDL:数据定义语言 DCL:数据控制语言,如授权 DML:数据操作语言 其它分类: 完整性定义语言: DDL的一 ...

  8. MySQL的变量分类总结

    在MySQL中,my.cnf是参数文件(Option Files),类似于ORACLE数据库中的spfile.pfile参数文件,照理说,参数文件my.cnf中的都是系统参数(这种称呼比较符合思维习惯 ...

  9. MySQL系统变量sql_safe_updates总结

    MySQL系统变量sql_safe_updates总结   在MySQL中,系统变量sql_safe_updates是个非常有意思的系统变量,在Oracle和SQL Server中都没有见过这样的参数 ...

随机推荐

  1. 拜托!面试请不要再问我Spring Cloud底层原理[z]

    [z]https://juejin.im/post/5be13b83f265da6116393fc7 拜托!面试请不要再问我Spring Cloud底层原理 欢迎关注微信公众号:石杉的架构笔记(id: ...

  2. Java Token的原理和生成使用机制

    在此之前我们先了解一下什么是Cookie.Session.Token 1.什么是Cookie? cookie指的就是浏览器里面能永久存储数据的一种数据存储功能.cookie由服务器生成,发送给浏览器, ...

  3. php正则提取html图片(img)src地址与任意属性的方法

    <?php /*PHP正则提取图片img标记中的任意属性*/ $str = '<center><img src="/uploads/images/2017020716 ...

  4. AX_Function

    formrun.owner().GetItemId() if (fr.name() == formstr(inventTransEditDimensions) || fr.name() == form ...

  5. 《Linux就该这么学》第八天课程

        当一个人的心中,有着更高的山峰想要去攀登时,他就不会在意脚下的泥沼. 今天发一下干货,常用命令的一些总结,今天的理论知识比较多. 原创地址:https://www.linuxprobe.com ...

  6. Java输入输出流详解

    通过数据流.序列化和文件系统提供系统输入和输出. Java把这些不同来源和目标的数据都统一抽象为数据流.Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为 ...

  7. Linux学习--- 宏定义下#、##的使用

    #   字符串化 ## 连接符号 eg: #include <stdio.h> #define ABC(x) #x #define DAY(c) myday##c int main (){ ...

  8. 走进JDK(五)------AbstractList

    接下来的一段时间重点介绍java.util这个包中的内容,这个包厉害了,包含了collection与map,提供了集合.队列.映射等实现.一张图了解java中的集合类: AbstractList 一. ...

  9. using python read/write HBase data

    A. operations on Server side 1. ensure hadoop and hbase are working properly 2. install thrift:  apt ...

  10. DE1-SOC资源

    1,digital solution lab 网站上的de1soc QT教程. 内容包括: Install Qt 5.4 Designer Install the Altera SoC Tool-Ch ...