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. Elasticsearch tshark 封包分析 (转)

    Elasticsearch tshark 封包分析 使用wireshark能解決許多網路問題,將側錄下來的封包傳至Elasticsearch上方便分析製作及時報表.tshark為wireshark的命 ...

  2. Linux用户态驱动设计

    聊聊Linux用户态驱动设计   序言 设备驱动可以运行在内核态,也可以运行在用户态,用户态驱动的利弊网上有很多的讨论,而且有些还上升到政治性上,这里不再多做讨论.不管用户态驱动还是内核态驱动,他们都 ...

  3. 【机器学习】Octave 实现逻辑回归 Logistic Regression

    ex2data1.txt ex2data2.txt 本次算法的背景是,假如你是一个大学的管理者,你需要根据学生之前的成绩(两门科目)来预测该学生是否能进入该大学. 根据题意,我们不难分辨出这是一种二分 ...

  4. Android单片机与蓝牙模块通信实例代码

    Android单片机与蓝牙模块通信实例代码 参考路径:http://www.jb51.net/article/83349.htm 啦啦毕业了,毕业前要写毕业设计,需要写一个简单的蓝牙APP进行交互,通 ...

  5. RDS MySQL InnoDB 锁等待和锁等待超时的处理

    https://help.aliyun.com/knowledge_detail/41705.html 1. Innodb 引擎表行锁等待和等待超时发生的场景 2.Innodb 引擎行锁等待情况的处理 ...

  6. CodeCraft-19 and Codeforces Round #537 (Div. 2) E 虚树 + 树形dp(新坑)

    https://codeforces.com/contest/1111/problem/E 题意 一颗有n个点的树,有q个询问,每次从树挑出k个点,问将这k个点分成m组,需要保证在同一组中不存在一个点 ...

  7. RISC与CISC比较

    1.RISC与CISC的差异 处理器的指令集可简单分为2种,CISC(complex instruction set computer)以及RISC(reduced instruction set c ...

  8. maven学习三

    做项目时使用maven构建项目已经是现在的流行做法了.那么maven的作用是什么呢?maven中的几个常用的命令都有什么用?下面我们来看一下. maven最大的作用就是用于对项目中jar包依赖的统一管 ...

  9. 关于使用Visual编译静态库动态库及其使用的问题

    本文主要讲述了如何使用Visual Studio 2013 编译静态库和动态库,并使用. 一.静态库 1.  编写静态库 若要创建将引用并使用刚创建的静态库的应用程序,请从“文件”菜单中选择“新建”, ...

  10. BASH 基本语法

    本节内容 1.  什么是shell script 2.  变量 3.  运算符 4.  流程控制 5.  函数 6.  计划任务 crontab 一  什么是shell script 将OS命令堆积到 ...