# 12.16 信息函数
表 12.20 信息函数
姓名 | 描述 |
---|---|
基准() | 重复执行一个表达式 |
字符集() | 返回参数的字符集 |
强制力() | 返回字符串参数的排序规则强制值 |
整理() | 返回字符串参数的排序规则 |
CONNECTION_ID() | 返回连接的连接 ID(线程 ID) |
目前角色() | 返回当前活跃的角色 |
当前用户() , 当前用户 | 认证的用户名和主机名 |
数据库() | 返回默认(当前)数据库名称 |
FOUND_ROWS() | 对于带有 LIMIT 子句的 SELECT,如果没有 LIMIT 子句,将返回的行数 |
ICU_VERSION() | ICU图书馆版本 |
LAST_INSERT_ID() | 最后一个 INSERT 的 AUTOINCREMENT 列的值 |
ROLES_GRAPHML() | 返回表示内存角色子图的 GraphML 文档 |
ROW_COUNT() | 更新的行数 |
架构() | DATABASE() 的同义词 |
SESSION_USER() | USER() 的同义词 |
SYSTEM_USER() | USER() 的同义词 |
用户() | 客户端提供的用户名和主机名 |
版本() | 返回一个表示 MySQL 服务器版本的字符串 |
-
这
基准()
函数执行表达式*表达式
反复数数
*次。它可用于计时 MySQL 处理表达式的速度。结果值为0
, 要么空值
对于不恰当的论点,例如空值
或负重复计数。预期用途是从内部mysql客户端,它报告查询执行时间:
mysql> SELECT BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')); +---------------------------------------------------+ | BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')) | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (4.74 sec)
报告的时间是客户端的经过时间,而不是服务器端的 CPU 时间。建议执行
基准()
几次,并根据服务器机器的负载程度来解释结果。基准()
旨在测量标量表达式的运行时性能,这对您使用它和解释结果的方式有一些重要影响:只能使用标量表达式。尽管表达式可以是子查询,但它必须返回单列且最多单行。例如,
基准(10, (SELECT * FROM t))
如果表失败吨
具有多于一列或多于一行。执行一个
选择 *
表达式*
陈述*ñ
时间不同于执行选择基准(*
ñ*, *
表达式*)
就所涉及的间接费用而言。两者具有非常不同的执行配置文件,您不应期望它们花费相同的时间。前者涉及解析器、优化器、表锁定和运行时评估ñ
每次。后者仅涉及运行时评估ñ
*次,而所有其他组件只需一次。已经分配的内存结构被重用,并且运行时优化(例如已经为聚合函数评估的结果的本地缓存)可以改变结果。用于基准()
因此,通过赋予该组件更多的权重并消除由网络、解析器、优化器等引入的“噪音”来衡量运行时组件的性能。
-
返回字符串参数的字符集。
mysql> SELECT CHARSET('abc'); -> 'utf8' mysql> SELECT CHARSET(CONVERT('abc' USING latin1)); -> 'latin1' mysql> SELECT CHARSET(USER()); -> 'utf8'
-
返回字符串参数的排序规则强制值。
mysql> SELECT COERCIBILITY('abc' COLLATE utf8_swedish_ci); -> 0 mysql> SELECT COERCIBILITY(USER()); -> 3 mysql> SELECT COERCIBILITY('abc'); -> 4 mysql> SELECT COERCIBILITY(1000); -> 5
返回值的含义如下表所示。较低的值具有较高的优先级。
强制力 意义 例子 0
显式排序规则 价值与 整理
条款1
无整理 具有不同排序规则的字符串连接 2
隐式整理 列值、存储的例程参数或局部变量 3
系统常数 用户()
返回值4
强制的 文字字符串 5
数字 数值或时间值 5
可忽略的 空值
或派生自的表达式空值
有关详细信息,请参阅第 10.8.4 节,“表达式中的排序规则强制性”.
-
返回字符串参数的排序规则。
mysql> SELECT COLLATION('abc'); -> 'utf8_general_ci' mysql> SELECT COLLATION(_utf8mb4'abc'); -> 'utf8mb4_0900_ai_ci' mysql> SELECT COLLATION(_latin1'abc'); -> 'latin1_swedish_ci'
-
返回连接的连接 ID(线程 ID)。每个连接都有一个在当前连接的客户端集合中唯一的 ID。
返回的值
CONNECTION_ID()
是与显示在相同类型的值ID
的列INFORMATION_SCHEMA.PROCESSLIST
表Id
列显示进程列表
输出,并且PROCESSLIST_ID
性能模式的列线程
桌子。mysql> SELECT CONNECTION_ID(); -> 23786
警告
更改会话值
伪线程 ID
系统变量改变了返回的值CONNECTION_ID()
功能。 -
返回一个
utf8
包含当前会话的当前活动角色的字符串,以逗号分隔,或没有
如果没有。该值反映了设置sql_quote_show_create
系统变量。假设一个帐户被授予如下角色:
GRANT 'r1', 'r2' TO 'u1'@'localhost'; SET DEFAULT ROLE ALL TO 'u1'@'localhost';
在会话中
u1
, 最初的目前角色()
value 命名默认帐户角色。使用设定角色
改变:mysql> SELECT CURRENT_ROLE(); +-------------------+ | CURRENT_ROLE() | +-------------------+ | `r1`@`%`,`r2`@`%` | +-------------------+ mysql> SET ROLE 'r1'; SELECT CURRENT_ROLE(); +----------------+ | CURRENT_ROLE() | +----------------+ | `r1`@`%` | +----------------+
-
返回服务器用于验证当前客户端的 MySQL 帐户的用户名和主机名组合。此帐户决定您的访问权限。返回值是一个字符串
utf8
字符集。mysql> SELECT USER(); -> 'davida@localhost' mysql> SELECT * FROM mysql.user; ERROR 1044: Access denied for user ''@'localhost' to database 'mysql' mysql> SELECT CURRENT_USER(); -> '@localhost'
该示例说明,尽管客户端指定了用户名
大卫
(由的值表示用户()
函数),服务器使用匿名用户帐户对客户端进行身份验证(如当前用户()
价值)。可能发生这种情况的一种方式是在授权表中没有为大卫
.在存储的程序或视图中,
当前用户()
返回定义对象的用户的帐户(由其给出的定义者
值)除非用SQL 安全调用程序
特征。在后一种情况下,当前用户()
返回对象的调用者。触发器和事件没有选项来定义
SQL 安全
特征,所以对于这些对象,当前用户()
返回定义对象的用户的帐户。要返回调用者,请使用用户()
要么SESSION_USER()
.以下语句支持使用
当前用户()
代替受影响用户或定义者的名称(并且可能是主机)的功能;在这种情况下,当前用户()
在需要的地方和需要时扩展: -
以字符串形式返回默认(当前)数据库名称
utf8
字符集。如果没有默认数据库,数据库()
返回空值
.在存储的例程中,默认数据库是例程关联的数据库,它不一定与调用上下文中的默认数据库相同。mysql> SELECT DATABASE(); -> 'test'
如果没有默认数据库,
数据库()
返回空值
. -
笔记
这
SQL_CALC_FOUND_ROWS
查询修饰符和伴随FOUND_ROWS()
自 MySQL 8.0.17 起,函数已弃用;期望它们在 MySQL 的未来版本中被删除。作为替代,考虑执行您的查询限制
,然后是第二个查询数数(*)
并且没有限制
确定是否有额外的行。例如,代替这些查询:SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10; SELECT FOUND_ROWS();
请改用这些查询:
SELECT * FROM tbl_name WHERE id > 100 LIMIT 10; SELECT COUNT(*) FROM tbl_name WHERE id > 100;
数数(*)
受到某些优化。SQL_CALC_FOUND_ROWS
导致某些优化被禁用。一种
选择
声明可能包括限制
子句来限制服务器返回给客户端的行数。在某些情况下,最好知道如果没有限制
,但没有再次运行该语句。要获得此行数,请包括SQL_CALC_FOUND_ROWS
中的选项选择
语句,然后调用FOUND_ROWS()
之后:mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name -> WHERE id > 100 LIMIT 10; mysql> SELECT FOUND_ROWS();
第二
选择
返回一个数字,指示第一个有多少行选择
如果没有限制
条款。在没有
SQL_CALC_FOUND_ROWS
最近成功的选项选择
陈述,FOUND_ROWS()
返回该语句返回的结果集中的行数。如果该语句包括限制
条款,FOUND_ROWS()
返回达到限制的行数。例如,FOUND_ROWS()
如果语句包括,则分别返回 10 或 60限制 10
要么限制 50、10
.可用的行数通过
FOUND_ROWS()
是暂时的,不打算在后面的语句之后可用选择 SQL_CALC_FOUND_ROWS
陈述。如果以后需要引用该值,请保存:mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ; mysql> SET @rows = FOUND_ROWS();
如果您正在使用
选择 SQL_CALC_FOUND_ROWS
, MySQL 必须计算完整结果集中有多少行。但是,这比在没有的情况下再次运行查询要快限制
,因为结果集不需要发送给客户端。SQL_CALC_FOUND_ROWS
和FOUND_ROWS()
在您想要限制查询返回的行数,但也确定完整结果集中的行数而不再次运行查询的情况下可能很有用。一个示例是一个 Web 脚本,它呈现一个分页显示,其中包含指向显示搜索结果其他部分的页面的链接。使用FOUND_ROWS()
使您能够确定其余结果需要多少其他页面。指某东西的用途
SQL_CALC_FOUND_ROWS
和FOUND_ROWS()
更复杂联盟
陈述比简单选择
陈述,因为限制
可能发生在多个地方联盟
.它可能适用于个人选择
中的陈述联盟
, 或全局的联盟
结果作为一个整体。的意图
SQL_CALC_FOUND_ROWS
为了联盟
是它应该返回没有全局返回的行数限制
.使用条件SQL_CALC_FOUND_ROWS
和联盟
是:的价值
FOUND_ROWS()
只有当联合所有
用来。如果联盟
没有全部
被使用,重复删除发生和值FOUND_ROWS()
只是近似值。如果不
限制
存在于联盟
,SQL_CALC_FOUND_ROWS
被忽略并返回临时表中为处理联盟
.除了这里描述的情况,
FOUND_ROWS()
未定义(例如,它的值跟在选择
因错误而失败的语句)。
重要的
FOUND_ROWS()
没有使用基于语句的复制可靠地复制。此函数使用基于行的复制自动复制。 -
用于支持正则表达式操作的 International Components for Unicode (ICU) 库的版本(请参阅第 12.8.2 节,“正则表达式”)。此功能主要用于测试用例。
-
LAST_INSERT_ID()
,LAST_INSERT_ID(*
表达式*)
没有争论,
LAST_INSERT_ID()
返回一个BIGINT 未签名
(64 位)值,表示成功插入的第一个自动生成的值自动递增
列作为最近执行的结果插入
陈述。的价值LAST_INSERT_ID()
如果没有成功插入行,则保持不变。带着论据,
LAST_INSERT_ID()
返回一个无符号整数。例如,在插入一行生成一个
自动递增
值,你可以得到这样的值:mysql> SELECT LAST_INSERT_ID(); -> 195
当前执行的语句不影响
LAST_INSERT_ID()
.假设您生成一个自动递增
用一个语句取值,然后参考LAST_INSERT_ID()
在多排插入
将行插入到具有自己的表中的语句自动递增
柱子。的价值LAST_INSERT_ID()
在第二个陈述中保持稳定;它对第二行和后面的行的值不受早期行插入的影响。(你应该知道,如果你混合引用LAST_INSERT_ID()
和LAST_INSERT_ID(*
表达式*)
,效果未定义。)如果前面的语句返回错误,则值为
LAST_INSERT_ID()
未定义。对于事务表,如果语句由于错误而回滚,则值为LAST_INSERT_ID()
未定义。对于手动回滚
, 的价值LAST_INSERT_ID()
没有恢复到交易前的状态;它保持原样回滚
.在存储例程(过程或函数)或触发器的主体内,
LAST_INSERT_ID()
更改方式与在这些对象的主体之外执行的语句相同。存储的例程或触发器对值的影响LAST_INSERT_ID()
以下语句所见取决于例程的类型:如果存储过程执行更改值的语句
LAST_INSERT_ID()
,更改后的值会被过程调用之后的语句看到。对于更改值的存储函数和触发器,该值会在函数或触发器结束时恢复,因此后面的语句不会看到更改的值。
生成的 ID 保存在服务器上的基于每个连接.这意味着函数返回给给定客户端的值是第一个
自动递增
为影响自动递增
柱子由那个客户.此值不会受到其他客户端的影响,即使它们生成自动递增
自己的价值观。这种行为确保每个客户端都可以检索自己的 ID,而不用担心其他客户端的活动,也不需要锁或事务。的价值
LAST_INSERT_ID()
如果您设置自动递增
行的列到非“魔术”值(即,不是空值
并不是0
)。
重要的
如果您使用单个插入多行
插入
陈述,LAST_INSERT_ID()
返回为第一的插入行只要.这样做的原因是可以很容易地复制相同的插入
针对其他服务器的声明。例如:
mysql> USE test; mysql> CREATE TABLE t ( id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, name VARCHAR(10) NOT NULL ); mysql> INSERT INTO t VALUES (NULL, 'Bob'); mysql> SELECT * FROM t; +----+------+ | id | name | +----+------+ | 1 | Bob | +----+------+ mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ mysql> INSERT INTO t VALUES (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa'); mysql> SELECT * FROM t; +----+------+ | id | name | +----+------+ | 1 | Bob | | 2 | Mary | | 3 | Jane | | 4 | Lisa | +----+------+ mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 2 | +------------------+
虽然第二
插入
语句插入了三个新行吨
,为这些行中的第一行生成的 ID 是2
, 正是这个值由LAST_INSERT_ID()
对于以下选择
陈述。如果你使用
插入忽略
并且该行被忽略,LAST_INSERT_ID()
与当前值保持不变(如果连接尚未成功,则返回 0插入
) 并且,对于非事务性表,自动递增
计数器不递增。为了InnoDB
表自动递增
计数器增加,如果innodb_autoinc_lock_mode
被设定为1
要么2
,如以下示例所示:mysql> USE test; mysql> SELECT @@innodb_autoinc_lock_mode; +----------------------------+ | @@innodb_autoinc_lock_mode | +----------------------------+ | 1 | +----------------------------+ mysql> CREATE TABLE `t` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `val` INT(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; # Insert two rows mysql> INSERT INTO t (val) VALUES (1),(2); # With auto_increment_offset=1, the inserted rows # result in an AUTO_INCREMENT value of 3 mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `val` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 # LAST_INSERT_ID() returns the first automatically generated # value that is successfully inserted for the AUTO_INCREMENT column mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ # The attempted insertion of duplicate rows fail but errors are ignored mysql> INSERT IGNORE INTO t (val) VALUES (1),(2); Query OK, 0 rows affected (0.00 sec) Records: 2 Duplicates: 2 Warnings: 0 # With innodb_autoinc_lock_mode=1, the AUTO_INCREMENT counter # is incremented for the ignored rows mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `val` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 # The LAST_INSERT_ID is unchanged because the previous insert was unsuccessful mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+
有关详细信息,请参阅第 15.6.1.6 节,“自动_InnoDB 中的增量处理”.
如果*
表达式
*作为参数给出LAST_INSERT_ID()
,参数的值由函数返回,并被记住为下一个要返回的值LAST_INSERT_ID()
.这可以用来模拟序列:创建一个表来保存序列计数器并对其进行初始化:
mysql> CREATE TABLE sequence (id INT NOT NULL); mysql> INSERT INTO sequence VALUES (0);
使用该表生成序列号,如下所示:
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1); mysql> SELECT LAST_INSERT_ID();
这
更新
语句递增序列计数器并导致下一次调用LAST_INSERT_ID()
返回更新的值。这选择
语句检索该值。这mysql_insert_id()
(opens new window)C API 函数也可用于获取值。看mysql_插入_ID() (opens new window).您无需调用即可生成序列
LAST_INSERT_ID()
,但是这种方式使用函数的用处是ID值作为最后一个自动生成的值保存在服务器中。它是多用户安全的,因为多个客户端可以发出更新
语句并使用选择
声明(或mysql_insert_id()
(opens new window)),而不会影响或受其他生成自己的序列值的客户端的影响。注意
mysql_insert_id()
(opens new window)之后才更新插入
和更新
语句,因此您不能使用 C API 函数来检索LAST_INSERT_ID(*
表达式*)
在执行其他 SQL 语句后选择
要么放
.
-
返回一个
utf8
包含表示内存角色子图的GraphML文档的字符串。这个角色管理
特权(或不推荐的超级的
权限)是查看中的内容所必需的<graphml>
要素否则,结果仅显示一个空元素:mysql> SELECT ROLES_GRAPHML(); +---------------------------------------------------+ | ROLES_GRAPHML() | +---------------------------------------------------+ | <?xml version="1.0" encoding="UTF-8"?><graphml /> | +---------------------------------------------------+
-
行计数()
返回一个值,如下所示:DML语句,而非
选择
:受影响的行数。这适用于以下语句:使现代化
,插入
或删去
(与之前一样),但现在也适用于以下声明:改变桌子
和加载数据
.选择
如果语句返回结果集,则返回-1;如果不返回,则返回“受影响”的行数。例如从t1中选择*
,行计数()
返回-1。对于选择*从t1到输出文件'*
文件名*'
,行计数()
返回写入文件的行数。信号
声明:0。对于
使现代化
语句中,默认情况下受影响的行数值是实际更改的行数。如果指定客户端\u找到\u行
向mysql_real_connect()
(opens new window)当连接到mysqld,受影响的行数值是“找到”的行数;也就是说,由哪里
条款对于
代替
语句,如果新行替换了旧行,则受影响的行的值为2,因为在这种情况下,在删除重复行后插入了一行。对于
插入关于重复密钥更新
语句中,如果将行作为新行插入,则每行受影响的行值为1,如果更新现有行,则为2,如果将现有行设置为其当前值,则为0。如果指定客户端\u找到\u行
如果将现有行设置为其当前值,则受影响的行值为1(而不是0)。这个
行计数()
值与mysql_受影响的_行()
(opens new window)C API函数和mysql客户端显示以下语句执行。
mysql> INSERT INTO t VALUES(1),(2),(3); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> SELECT ROW_COUNT(); +-------------+ | ROW_COUNT() | +-------------+ | 3 | +-------------+ 1 row in set (0.00 sec) mysql> DELETE FROM t WHERE i IN(1,2); Query OK, 2 rows affected (0.00 sec) mysql> SELECT ROW_COUNT(); +-------------+ | ROW_COUNT() | +-------------+ | 2 | +-------------+ 1 row in set (0.00 sec)
重要的
行计数()
无法使用基于语句的复制进行可靠复制。使用基于行的复制自动复制此功能。 -
此函数是
数据库()
. -
笔记
这个
系统_用户()
功能不同于系统用户
特权前者返回当前MySQL帐户名。后者区分系统用户和常规用户帐户类别(参见第6.2.11节“账户类别”). -
以字符串形式返回当前MySQL用户名和主机名
utf8
角色集。mysql> SELECT USER(); -> 'davida@localhost'
该值表示连接到服务器时指定的用户名,以及连接的客户端主机。该值可能与的值不同
当前用户()
. -
返回指示MySQL服务器版本的字符串。字符串使用
utf8
角色集。除了版本号之外,该值可能还有一个后缀。请参见对版本
系统变量第5.1.8节“服务器系统变量”.此函数对于基于语句的复制不安全。如果在以下情况下使用此功能,将记录警告:
binlog_格式
即将陈述
.mysql> SELECT VERSION(); -> '8.0.28-standard'