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. swap的实现(没有中间变量)

    两数交换最常用的方法 void swap(int &a,int &b) { int temp=a; a=b; b=temp; } 如果没有中间变量temp可以使用呢,还有其他的三种方法 ...

  2. c++11 线程池学习笔记 (二) 线程池

    学习内容来自以下地址 http://www.cnblogs.com/qicosmos/p/4772486.html github https://github.com/qicosmos/cosmos ...

  3. C++标准库第二版笔记 1

    C++标准库第二版笔记 1 C++ std历史 第一份标准化文档: C++98 & C++03 & TR1 TR1 Information Technology- Programmin ...

  4. Java集合:LinkedList源码解析

    Java集合---LinkedList源码解析   一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...

  5. MFC 字体

    dc.DrawText(_T("hello"), -1, //全部 &rect, DT_SINGLELINE| //在一行 DT_CENTER| //水平居中 DC_VCE ...

  6. tar打包如何不打包某一个文件夹(排除某些文件夹)

    tar打包如何不打包某一个文件夹(排除某些文件夹) 问题描述: 最近想备份一下Tomcat运行的的功能文件,以防特殊情况的发生.但是在实际操作的过程中发现,可能是由于Unix/Linux版本太老的原因 ...

  7. EF6学习笔记(六) 创建复杂的数据模型

    EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 本篇原文地址:Creating a More Complex Data Model 本篇讲的比较碎,很多内容本人 ...

  8. springboot之使用redistemplate优雅地操作redis

    概述 本文内容主要 关于spring-redis 关于redis的key设计 redis的基本数据结构 介绍redis与springboot的整合 sringboot中的redistemplate的使 ...

  9. Jmeter 结构、原理介绍 Jmeter结构、原理介绍(1)

    一.Jmeter 简介 1.是基于java语言的开源的应用软件. 2.可以进行接口测试.性能测试.接口及性能的自动化测试. 二.Jmeter体系结构 元件:可以理解为每一个菜单.如THHP请求.响应断 ...

  10. hdoj6483 A Sequence Game(ST预处理RMQ+莫队)

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6483 题意:有长度为$n$的数组,对于一个子区间$[l,r]$内,存在最大值$mx$与最小值$mi$,有$ ...