# 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'
    
  • CONNECTION_ID()

    返回连接的连接 ID(线程 ID)。每个连接都有一个在当前连接的客户端集合中唯一的 ID。

    返回的值CONNECTION_ID()是与显示在相同类型的值ID的列INFORMATION_SCHEMA.PROCESSLISTId显示进程列表输出,并且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'
    

    如果没有默认数据库,数据库()返回空值.

  • FOUND_ROWS()

    笔记

    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_ROWSFOUND_ROWS()在您想要限制查询返回的行数,但也确定完整结果集中的行数而不再次运行查询的情况下可能很有用。一个示例是一个 Web 脚本,它呈现一个分页显示,其中包含指向显示搜索结果其他部分的页面的链接。使用FOUND_ROWS()使您能够确定其余结果需要多少其他页面。

    指某东西的用途SQL_CALC_FOUND_ROWSFOUND_ROWS()更复杂联盟陈述比简单选择陈述,因为限制可能发生在多个地方联盟.它可能适用于个人选择中的陈述联盟, 或全局的联盟结果作为一个整体。

    的意图SQL_CALC_FOUND_ROWS为了联盟是它应该返回没有全局返回的行数限制.使用条件SQL_CALC_FOUND_ROWS联盟是:

    • SQL_CALC_FOUND_ROWS关键字必须出现在第一个选择联盟.

    • 的价值FOUND_ROWS()只有当联合所有用来。如果联盟没有全部被使用,重复删除发生和值FOUND_ROWS()只是近似值。

    • 如果不限制存在于联盟,SQL_CALC_FOUND_ROWS被忽略并返回临时表中为处理联盟.

      除了这里描述的情况,FOUND_ROWS()未定义(例如,它的值跟在选择因错误而失败的语句)。

    重要的

    FOUND_ROWS()没有使用基于语句的复制可靠地复制。此函数使用基于行的复制自动复制。

  • ICU_VERSION()

    用于支持正则表达式操作的 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().这可以用来模拟序列:

    1. 创建一个表来保存序列计数器并对其进行初始化:

      mysql> CREATE TABLE sequence (id INT NOT NULL);
      mysql> INSERT INTO sequence VALUES (0);
      
    2. 使用该表生成序列号,如下所示:

      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 语句后选择要么.

  • ROLES_GRAPHML()

    返回一个utf8包含表示内存角色子图的GraphML文档的字符串。这个角色管理特权(或不推荐的超级的权限)是查看中的内容所必需的<graphml>要素否则,结果仅显示一个空元素:

    mysql> SELECT ROLES_GRAPHML();
    +---------------------------------------------------+
    | ROLES_GRAPHML()                                   |
    +---------------------------------------------------+
    | <?xml version="1.0" encoding="UTF-8"?><graphml /> |
    +---------------------------------------------------+
    
  • 行计数()

    行计数()返回一个值,如下所示:

    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'