• Atitit mysql insert perf enhance 批量插入数据库性能 目录 1.1. 案一:使用ignore关键字 1 2. 异步插入 2 2.1. 其它关键:DELAYED  做为


    Atitit mysql insert perf enhance 批量插入数据库性能

     

    目录

    1.1. 案一:使用ignore关键字 1

    2. 异步插入 2

    2.1. 其它关键:DELAYED  做为快速插入,并不是很关心失效性,提高插入性能。 IGNORE  只关注主键对应记录是不存在,无则添加,有则忽略。 2

    2.2. 13.2.5.3 INSERT DELAYED语句  异步 2

    2.3. 多线程  批量  java级别 5

    3. other 5

    3.1. Archil引擎 5

    3.2. Mem引擎 5

    3.3. 严禁批量更新默认是一个长事务 6

    3.4. 检查移除多进程,防止多个进程同时更改同一记录 6

    4. Other 6

    4.1. 方案三:ON DUPLICATE KEY UPDATE 6

     

     

      1. 案一:使用ignore关键字



    如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用:

    INSERT IGNORE INTO `table_name` (`email`, `phone`, `user_id`)

    VALUES ('test9@163.com', '99999', '9999');

     

    这样当有重复记录就会忽略,执行后返回数字0

    1. 异步插入
      1. 其它关键:DELAYED  做为快速插入,并不是很关心失效性,提高插入性能。
        IGNORE  只关注主键对应记录是不存在,无则添加,有则忽略。

     

    MySQL 5.6参考手册  /  ...  /  INSERT DELAYED语句

      1. 13.2.5.3 INSERT DELAYED语句  异步

    INSERT DELAYED ...

    该语句的DELAYED选项 INSERT是对标准SQL的MySQL扩展,可用于某些类型的表(例如MyISAM)。当客户端使用时 INSERT DELAYED,它将立即从服务器获得许可,并且当该表未被任何其他线程使用时,该行将排队插入。

    注意

    INSERT DELAYEDINSERT如果不使用该表,则它比正常速度慢。服务器还要为每个有延迟行的表处理一个单独的线程,这会产生额外的开销。这意味着INSERT DELAYED仅在确实确定需要时才应使用 。

    从MySQL 5.6.6开始,INSERT DELAYED已弃用,并将在以后的版本中删除。使用INSERT (不带DELAYED)代替。

    排队的行仅保留在内存中,直到将它们插入表中为止。这意味着,如果强行终止mysqld(例如,使用 kill -9)或mysqld意外终止 ,则所有尚未写入磁盘的排队行都将丢失

    使用以下限制 DELAYED

    •  

    INSERT DELAYED只有工作MyISAMMEMORY, ARCHIVE,和BLACKHOLE 表格。对于不支持的引擎, DELAYED会发生错误。

    •  
    •  

    INSERT DELAYED如果将其与已锁定的表一起使用, 则会发生错误,LOCK TABLES因为插入必须由单独的线程而不是由持有锁的会话处理。

    •  
    •  

    对于MyISAM表,如果数据文件中间没有空闲块,则支持并发 SELECT和 INSERT语句。在这种情况下,你很少需要使用INSERT DELAYED带 MyISAM

    •  
    •  

    INSERT DELAYED仅应用于INSERT指定值列表的语句。服务器忽略 DELAYEDfor INSERT ... SELECT或 INSERT ... ON DUPLICATE KEY UPDATE语句。

    •  
    •  

    因为该INSERT DELAYED 语句立即返回,所以在插入行之前,您不能使用它 LAST_INSERT_ID()来获取AUTO_INCREMENT该语句可能生成的 值。

    •  
    •  

    DELAYEDSELECT实际插入之前,行对语句不可见 。

    •  
    •  

    INSERT DELAYED每当is 或的值时,将作为简单的INSERT(即不带DELAYED选项)进行处理。(在后一种情况下,该语句不会触发切换到基于行的日志记录,因此将使用基于语句的格式进行记录。) binlog_formatSTATEMENTMIXED

    •  

    当使用基于行的二进制日志记录模式(binlog_format设置为 ROW)时,该方法不适用,在该模式下, INSERT DELAYED始终使用DELAYED指定的选项执行语句并将其记录为行更新事件。

    •  
    •  

    DELAYED在从属复制服务器上被忽略,因此在从属服务器上INSERT DELAYED被视为正常 INSERT。这是因为DELAYED可能导致从机拥有与主机不同的数据。

    •  
    •  

    INSERT DELAYED 如果表被写锁定并ALTER TABLE用于修改表结构,则 待处理语句将丢失 。

    •  
    •  

    INSERT DELAYED 视图不支持。

    •  
    •  

    INSERT DELAYED 不支持分区表。

    •  

    以下详细描述了使用DELAYED选项 INSERT或 时会发生什么 REPLACE。在本说明中, “ 线程 ”是接收INSERT DELAYED语句 的线程, “ 处理程序 ”是处理INSERT DELAYED特定表的所有语句的线程 。

    •  

    当线程执行DELAYED 表的DELAYED语句时,如果尚不存在处理程序线程,则会创建一个处理程序线程来处理该表的所有语句。

    •  
    •  

    线程检查处理程序以前是否已获取DELAYED锁;如果不是,它告诉处理程序线程这样做。DELAYED 即使其他线程在表上具有READWRITE锁,也可以获得该锁 。但是,处理程序将等待所有 ALTER TABLE锁或 FLUSH TABLES语句完成,以确保表结构是最新的。

    •  
    •  

    该线程执行该 INSERT语句,但不是将行写入表中,而是将最后一行的副本放入由处理程序线程管理的队列中。该线程会发现任何语法错误,并将其报告给客户端程序。

    •  
    •  

    客户端无法从服务器获取重复的行数或AUTO_INCREMENT 结果行的值,因为 INSERT插入操作完成之前的返回。(如果使用C API,则mysql_info()由于相同的原因,该函数不会返回任何有意义的信息。)

    •  
    •  

    当将行插入表中时,处理程序线程会更新二进制日志。如果是多行插入,则在插入第一行时更新二进制日志。

    •  
    •  

    每次 delayed_insert_limit写入行时,处理程序都会检查是否还有任何 SELECT语句尚未处理。如果是这样,则允许它们在继续之前执行。

    •  
    •  

    当处理程序的队列中没有更多行时,该表将被解锁。如果INSERT DELAYEDdelayed_insert_timeout 几秒钟内未收到新语句 ,则处理程序终止。

    •  
    •  

    如果delayed_queue_size在特定处理程序队列中有多个 行挂起,则请求线程 INSERT DELAYED等待,直到队列中有空间为止。这样做是为了确保 mysqld不会将所有内存用于延迟的内存队列。

    •  
    •  

    处理程序线程显示在MySQL进程列表 delayed_insert中的 Command列中。如果执行一条FLUSH TABLES 语句或使用杀死它,它将被杀死。但是,在退出之前,它首先将所有排队的行存储到表中。在此期间,它不接受来自其他线程的任何新 语句。如果在此之后执行语句,则会创建一个新的处理程序线程。 KILL thread_idINSERTINSERT DELAYED

    •  

    这意味着,如果有 处理程序正在运行,则INSERT DELAYED语句的优先级高于普通INSERT语句INSERT DELAYED。其他更新语句必须等到INSERT DELAYED队列为空,有人终止处理程序线程(带有 )或有人执行。 KILL thread_idFLUSH TABLES

    •  
    •  

    以下状态变量提供有关INSERT DELAYED语句的信息 。

    •  

    状态变量

    含义

    Delayed_insert_threads

    处理程序线程数

    Delayed_writes

    写入的行数 INSERT DELAYED

    Not_flushed_delayed_rows

    等待写入的行数

    •  

    您可以通过发出SHOW STATUS语句或执行mysqladmin extended-status 命令来查看这些变量 。

     

      1. 多线程  批量  java级别
    1. other
      1. Archil引擎
      2. Mem引擎

    去除插入触发器,改为update触发器模式  手动刷新

    在没有更新update之前,加个fullfld标识。。可以不在select显示,只有update过了,才在ui显示

     

    插入触发器改用代码实现 一次更新一条

      1. 严禁批量更新默认是一个长事务

     可用代码拆分细分

      1. 检查移除多进程,防止多个进程同时更改同一记录

     

    1. Other

     

      1. 方案三:ON DUPLICATE KEY UPDATE

    如‍上所写,你也可以在INSERT INTO…..后面加上 ON DUPLICATE KEY UPDATE方法来实现。如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE。

    您可以在UPDATE子句中使用VALUES(col_name)函数从INSERT…UPDATE语句的INSERT部分引用列值。换句话说,如果没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函数特别适用于多行插入。VALUES()函数只在INSERT…UPDATE语句中有意义,其它时候会返回NULL。

    INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3), (4, 5, 6)

    ON DUPLICATE KEY UPDATE `c`=VALUES(`a`)+VALUES(`b`);

    本语句与以下两个语句作用相同:

    INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE `c`=3; 

    INSERT INTO `table` (`a`, `b`, `c`) VALUES (4, 5, 6) ON DUPLICATE KEY UPDATE c=9;

     

     

     

  • 相关阅读:
    中序遍历【递归算法】和【非递归算法】
    等价无穷小替换
    轮转访问MAC协议
    曲率
    Java I/O流 01
    Java 集合框架 04
    Java 集合框架 03
    Java 集合框架 02
    Java 集合框架 01
    Java 常见对象 05
  • 原文地址:https://www.cnblogs.com/attilax/p/15196921.html
Copyright © 2020-2023  润新知