• MySQL系统变量sql_safe_updates总结


    MySQL系统变量sql_safe_updates总结

     

    在MySQL中,系统变量sql_safe_updates是个非常有意思的系统变量,在Oracle和SQL Server中都没有见过这样的参数或功能。如果这个系统变量设置为1的话,意味着update与delete将会受到限制。个人臆测,之所以提供这个功能,一方面是要避免出现更新或删除数据时,忘记添加WHERE条件,导致数据被误更新或误删的情况。相信不少人都由于疏忽或大意,遇到过这种情况; 另外一方面也是为了提高SQL性能考虑,避免DELETE与UPDATE语句的WHERE条件不走索引的情况。默认情况下,系统变量sql_safe_updates是禁用的。我们下面来简单测试、了解一下这个系统变量的细节问题

     

    系统变量sql_safe_updates分会话级别和全局级别。可以动态修改。默认是关闭(值为0)。具体参考官方文档。

     

    系统变量的查看

     

    注意事项1:show variables优先显示会话级变量的系统变量值,如果这个系统变量没有会话级别的值,则显示全局级系统变量的值,当然最清晰的方式就是加上GLOBAL或SESSION关键字来区别。

    注意事项2:@@GLOBAL.var_name、@@SESSION.var_name 、@@LOCAL.var_name 。如果在变量名前没有级别限定符,将优先显示会话级的值。

     

    1:查看会话级别系统变量sql_safe_updates的值

     

    mysql> show variables like 'sql_safe_updates';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | sql_safe_updates | ON    |
    +------------------+-------+
    1 row in set (0.01 sec)
     
    mysql> show session variables like 'sql_safe_updates';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | sql_safe_updates | ON    |
    +------------------+-------+
    1 row in set (0.00 sec)
     
    mysql> 
    mysql> select @@session.sql_safe_updates;
    +----------------------------+
    | @@session.sql_safe_updates |
    +----------------------------+
    |                          1 |
    +----------------------------+
    1 row in set (0.00 sec)
     
    mysql> select @@sql_safe_updates;
    +--------------------+
    | @@sql_safe_updates |
    +--------------------+
    |                  1 |
    +--------------------+
    1 row in set (0.00 sec)

     

    2:查看全局级别系统变量sql_safe_updates的值

     

     

    mysql> show global variables like 'sql_safe_updates';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | sql_safe_updates | OFF   |
    +------------------+-------+
    1 row in set (0.00 sec)
     
    mysql> select @@global.sql_safe_updates;
    +---------------------------+
    | @@global.sql_safe_updates |
    +---------------------------+
    |                         0 |
    +---------------------------+
    1 row in set (0.00 sec)

     

     

    系统变量sql_safe_updates的设置

     

     

    #设置会话级别的系统变量

    mysql> set sql_safe_updates=1;

    Query OK, 0 rows affected (0.00 sec)

     

     

    #设置全局级别的系统变量

    mysql> set global sql_safe_updates=1;

    Query OK, 0 rows affected (0.00 sec)

     

    如果要设置全局级别的系统变量sql_safe_updates,最好在配置文件my.cnf中设置,这样就能避免MySQL重启后,SQL命令设置的sql_safe_updates系统全局变量失效。

     

     

     

     

    实验测试案例

     

    UPDATE语句测试

     

    1: 没有WHERE条件。

     

     

    mysql> update shop set price=price*1.5;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql> 

     

     

    2: 没有WHERE条件,但是有LIMTI限制条件

     

    如下测试所示,没有WHERE条件,但是有LIMIT限制的话,SQL也是可以执行的。

     

    mysql> update shop set price=price*1.5 limit 5;
    Query OK, 5 rows affected (0.05 sec)
    Rows matched: 5  Changed: 5  Warnings: 0

     

     

    3: 有WHERE条件,但是WHERE条件的列没有索引可用

     

    mysql> show index from shopG;
    *************************** 1. row ***************************
            Table: shop
       Non_unique: 0
         Key_name: PRIMARY
     Seq_in_index: 1
      Column_name: article
        Collation: A
      Cardinality: 931203
         Sub_part: NULL
           Packed: NULL
             Null: 
       Index_type: BTREE
          Comment: 
    Index_comment: 
    *************************** 2. row ***************************
            Table: shop
       Non_unique: 0
         Key_name: PRIMARY
     Seq_in_index: 2
      Column_name: dealer
        Collation: A
      Cardinality: 931203
         Sub_part: NULL
           Packed: NULL
             Null: 
       Index_type: BTREE
          Comment: 
    Index_comment: 
    *************************** 3. row ***************************
            Table: shop
       Non_unique: 1
         Key_name: shop__price
     Seq_in_index: 1
      Column_name: price
        Collation: A
      Cardinality: 1877
         Sub_part: NULL
           Packed: NULL
             Null: 
       Index_type: BTREE
          Comment: 
    Index_comment: 
    3 rows in set (0.00 sec)
     
    ERROR: 
    No query specified
     
    mysql> update shop set price = price * 1.5 where dealer='K';
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

     

    4: 有WHERE条件,但是WHERE条件列没有索引 + LIMIT限制

     

     

    mysql> update shop set price = price * 1.5 where dealer='K' limit 1000;
    Query OK, 1000 rows affected (0.13 sec)
    Rows matched: 1000  Changed: 1000  Warnings: 0

     

     

    5:有WHERE条件的UPDATE,而且字段有索引

     

    mysql> update shop set price = price * 1.5 where article=6156;
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
     
    mysql> 

     

    6:有WHERE条件,但是WHERE条件为常量

     

    mysql>  update shop set price = price * 1.5 where 1=1;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

     

     

    7:有WHERE条件,但是WHERE条件为常量+LIMIT

     

    mysql> update shop set price = price * 1.5 where 1=1 limit 10;
    Query OK, 10 rows affected (0.00 sec)
    Rows matched: 10  Changed: 10  Warnings: 0

     

     

    DELETE语句测试

     

     

    1: DELETE语句没有WHERE条件

     

     

    mysql> delete from shop;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql>

     

    2:  DELETE语句没有WHERE条件+ LIMIT

     

     

    mysql> delete from shop limit 10;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql> 

     

    3:DELETE语句有WHERE条件,而且查询条件的字段有索引

     

    mysql> delete from shop where article =6156;
    Query OK, 1 row affected (0.01 sec)
     
    mysql>

     

    4:DELETE语句有WHERE条件,而且查询条件的字段有索引 +LIMIT

     

     

    mysql> delete from shop where article< 2000 limit 1000;
    Query OK, 1000 rows affected (0.02 sec)
     
    mysql>

     

    5:DELETE语句有WHERE条件,但是查询条件的字段没有索引

     

     

    mysql> delete from shop where dealer='K';
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql>  

     

     

    6:DELETE语句有WHERE条件,但是查询字段没有索引 +LIMIT语句

     

    mysql> delete from shop where dealer='K' limit 20;
    Query OK, 20 rows affected (0.05 sec)
     
    mysql> 

     

    7:DELETE语句有WHERE条件,但是WHERE条件为常量

     

    mysql>  delete from shop where 1=1;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql>

     

     

    8:DELETE语句有WHERE条件,但是WHERE条件为常量 +LIMIT

     

    mysql> delete from shop where 1=1 limit 10;
    ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
    mysql>

     

     

    如上测试的实验结果,总结出来如下所示.至于是否要开启这个系统变量,需要结合实际情况,并且和开发人员、项目管理人员一起协商才行。

     

     

    操作

    Delete

    Update

    NO WHERE

    No

    No

    NO WHERE + LIMIT

    No

    Yes

    WHERE KEY

    Yes

    Yes

    WHERE KEY + LIMIT

    Yes

    Yes

    WHERE NOKEY

    No

    No

    WHERE NOKEY+ LIMIT

    Yes

    Yes

    WHERE CONSTANT

    No

    No

    WHERE CONSTANT + LIMIT

    No

    Yes

  • 相关阅读:
    leetcode 309. Best Time to Buy and Sell Stock with Cooldown
    leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee
    leetcode 32. Longest Valid Parentheses
    leetcode 224. Basic Calculator
    leetcode 540. Single Element in a Sorted Array
    leetcode 109. Convert Sorted List to Binary Search Tree
    leetcode 3. Longest Substring Without Repeating Characters
    leetcode 84. Largest Rectangle in Histogram
    leetcode 338. Counting Bits
    git教程之回到过去,版本对比
  • 原文地址:https://www.cnblogs.com/kerrycode/p/10569457.html
Copyright © 2020-2023  润新知