MySQL中UPDATE语句用法教学

  • 更新时间:2020-05-13 14:13:38
  • 编辑:咸清茹

一、UPDATE常见用法

首先建立测试环境:

DROP TABLE IF EXISTS t_test;
CREATE TABLE t_test (
 bs bigint(20) NOT NULL auto_increment,
 username varchar(20) NOT NULL,
 password varchar(20) default NULL,
 remark varchar(200) default NULL,
 PRIMARY KEY (bs)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=gbk;
 
 
INSERT INTO t_test VALUES (1,'lavasoft','123456',NULL);
INSERT INTO t_test VALUES (2,'hello',NULL,NULL);
INSERT INTO t_test VALUES (3,'haha',zz,tt);

 
1、set一个字段
在表t_test中设置第二条记录(bs为2)的password为'***'。

update t_test t 
  set t.password = '***' 
 where t.bs = 2;

 
2、set多个字段
在表t_test中设置第一条记录(bs为1)的password为'*'、remark为'*'。

update t_test t 
  set t.password = '*', t.remark = '*' 
 where t.bs = 1;

 
3、set null值
在表t_test中设置第三条记录(bs为3)的password为null、remark为null。

update t_test t 
  set t.password = null, t.remark = null 
 where t.bs = 3;

 
这个是按照标准语法写的,在不同的数据库系统中,update还有更多的写法,但是标准写法都是支持的。以上三个例子为了说明情况,每次都更新一行。在实际中,可以通过where语句约束来控制更新行数。

二、UPDATE使用中的相关性能问题以及解决方法
UPDATE的功能是更新表中的数据。这的语法和INSERT的第二种用法相似。必须提供表名以及SET表达式,在后面可以加WHERE以限制更新的记录范围。

UPDATE table_anem SET column_name1 = value1, column_name2 = value2,  WHERE ;

如下面的语句将users表中id等于123的记录的age改为24

UPDATE users SET age = 24 WHERE id = 123;

同样,可以使用UPDATE更新多个字段的值

UPDATE users SET age = 24, name = 'Mike' WHERE id = 123;

上面的UPDATE语句通过WHERE指定一个条件,否则,UPDATE将更新表中的所有记录的值
百万级别的数据,对于mysql应该没有问题。

你这个sql的问题是,相当于修改ONE表里面所有记录的AGE信息,而修改的过程是,对于每一条ONE里面的记录,去TWO里面查询,再修改。而且,期间很可能会有锁之类的东西。
首先,这种sql不应该出现在业务逻辑里面,而应该是后台的job里面。
如果一定要这么做,可以试着用相反的方式,如果不一样的记录不是特别多,那就找到ONE表里面AGE记录跟TWO表不一样的记录,再修改, 例如大概象下面(可能语法不太对):

update ONE,TWO 
set ONE.AGE=TWO.AGE 
where ONE.ID=TWO.ID AND ONE.AGE != TWO.AGE 

当我把数据调到了1000W就更新不了了,下面我来分析原因。
实例:需要根据用户日志的ip地址计算出其地理地址
表结构:
用户日志表(200万条记录),其中address是待填充的字段:

CREATE TABLE `tmp_open_ip` (
 `email` varchar(60) NOT NULL DEFAULT '',
 `address` varchar(50) NOT NULL DEFAULT '',
 `ip` int(10) unsigned NOT NULL DEFAULT '0',
 KEY `email` (`email`),
 KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

另ip地址数据库表(44万条记录)

CREATE TABLE `ip` (
`s` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '开始ip',
`e` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '结束ip',
`a` varchar(50) NOT NULL DEFAULT '',
KEY `s` (`s`),
KEY `e` (`e`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

需要根据用户日志表 tmp_open_ip 里的 ip字段到ip地址数据库表里查询出对应的地理地址,将地址填充到address字段。
使用如下update语句执行:

UPDATE tmp_open_ip AS u 
INNER JOIN ip 
ON u.ip BETWEEN ip.s AND ip.e 
SET u.address = ip.a

在笔者的电脑上运行了速度非常之慢,执行了一个多小时(4500s)都没有完,也不知道还要多久。
实在看不过去,于是想到使用insert 是否会快一些,于是重新导一张表 tmp_open_log 与tmp_open_log完全一致。
创建一张表 tmp_open_address,是insert的目标表,为了速度更快,没建索引:

CREATE TABLE `tmp_open_address` (
`email` varchar(60) NOT NULL DEFAULT '',
`address` varchar(50) NOT NULL DEFAULT '',
`ip` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8

执行insert 语句

insert into tmp_open_address (email,address,ip)
select l.email,ip.a,l.ip
 from tmp_open_log as l inner join ip on l.ip between ip.s and ip.e ;
/* Affected rows: 2,543,124 Found rows: 0 Warnings: 0 Duration for 3 queries: 16.922 sec. */

不到17s!本来还想去倒杯水、稍事休息一下,结果已经执行完毕。

到本文写完时,前面的update语句已经执行了5000s,结束仍是遥遥无期。
所以,对于大数据量执行update时,可以考虑改用insert 语句实现,可能麻烦一些,但高速带来的收益远大于麻烦!
后记:
直接杀死了update进程,去看看update执行了多少:运行

SELECT * FROM `tmp_open_ip` where address!=''

结果只有 11,373 ,照这个速度,要运行N天....

相关教程

  • 实例分享PHP操作MySql的增删改查的方法

    下面小编就为大家带来一篇利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    发布时间:2020-03-07

  • MySQL 扩展正则表达式模式匹配 字符串模式匹配知识点分享

    MySQL提供标准的SQL模式匹配,以及一种基于象Unix实用程序如vi、grep和sed的扩展正则表达式模式匹配的格式。

    发布时间:2020-01-30

  • mysql数据库保留小数位的实现讲解

    本篇文章是对关于在数据库中保留小数位的问题进行了详细的分析介绍,需要的朋友参考下

    发布时间:2020-02-02

  • MySQL数据库查看数据表占用空间大小和记录数的实例讲解

    这篇文章主要介绍了MySQL数据库查看数据表占用空间大小和记录数的方法,如果想知道MySQL数据库中每个表占用的空间、表记录的行数的话,可以打开MySQL的information_schema 数据库查询,本文就讲解查

    发布时间:2019-07-25

  • mysql 5.7.21解压版本、Navicat数据库工具安装详解

    这篇文章主要为大家详细介绍了mysql 5.7.21解压版本安装,Navicat数据库操作工具安装,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    发布时间:2019-12-03

  • MySQL DBA修炼之道

    MySQL DBA修炼之道

    MySQL DBA修炼之道 以实战讲解为主,摒弃了生产实践中不常用的知识和技术。书中内容主要分为5部分。第壹部分介绍MySQL的应用领域和适用场景、基础架构、常见生产环境部署方式,以及MySQL安

    大小:4.9 MBMySQL电子书

  • PHP与MySQL高性能应用开发

    PHP与MySQL高性能应用开发

    PHP与MySQL高性能应用开发书中不仅讲解了OOP、设计模式,也讲解了如何进行性能优化和调试。甚至,还对于语言之外的代码重构进行了讲解,本书面向的对象是有一定PHP基础,但是又想深入学习的PHP开发者,欢迎免费下载

    大小:60.5 MBPHP开发电子书

  • MySQL入门经典

    MySQL入门经典

    《 MySQL入门经典 》以新手为关键,全方位解读MySQL数据库系统。在內容分配上由浅人深,让用户由浅入深地把握编程技术;在內容解读上融合丰富多彩的详解和品牌形象的形容,协助用户了解

    大小:313.3 MBMySQL入门电子书

  • MySQL技术精粹:架构、高级特性、性能优化与集群实战

    MySQL技术精粹:架构、高级特性、性能优化与集群实战

    这书对于MySQL高级客户,详尽解读MySQL高級应用技术性。书中详细说明了每一个知识结构图及其数据库实际操作的方式和方法。这书重视实战实际操作,协助读者由浅入深地把握MySQL中的各类高

    大小:271.3 MBMySQL电子书

  • 零点起飞学MySQL

    零点起飞学MySQL

    本书是一本MySQL的入门教程,是手把手教会读者使用该数据库的入门教程。本书概念清楚,用穿插类比和图解的方式进行讲解,可以让读者更加直观地理解和掌握MySQL的各个知识点。本书附带1张光盘,收录了本书配套多媒体教学视频及涉及的源文件,便于读者高效、直观地学习。

    大小:85.8 MBMySQL入门电子书

  • MySQL技术内幕:InnoDB存储引擎

    MySQL技术内幕:InnoDB存储引擎

    《MySQL技术内幕:InnoDB存储引擎(第2版)》 由国内资深MySQL专家亲自执笔,国内外多位数据库专家联袂推荐。作为国内唯一一本关于InnoDB的专著,《MySQL技术内幕:InnoDB存储引擎(第2版)》的第1版广受

    大小:39.3 MBMySQL电子书

  • MySQL 8从入门到精通

    MySQL 8从入门到精通

    MySQL被设计方案为1个可移植的数据库查询,基本上能在当今全部的电脑操作系统上运作,如Linux、Solaris、FreeBSD、Mac和Windows。开源系统MySQL数据库查询发展趋势到今日,早已具备了十分普遍的客

    大小:168 MBMySQL8

  • PHP、MySQL与JavaScript学习手册(第4版)

    PHP、MySQL与JavaScript学习手册(第4版)

    本书有借助面向对象的编程基础,深入学习PHP。研究MySQL,从数据库结构到复杂查询。掌握JavaScript语言,以及带有jQuery的增强功能。调用Ajax进行后台浏览器/服务器通信等,欢迎免费下载

    大小:76 MBPHP学习手册电子书

  • 高性能MySQL

    高性能MySQL

    大小:392 MBMySQL电子书

  • MySQL运维内参

    MySQL运维内参

    《MySQL运维内参:MySQL、Galera、Inception核心原理与最佳实践》是一本介绍MySQL数据库知识的专业书籍,从核心原理到最佳实践,深入浅出、抽丝剥茧地进行讲解,不仅从源码和运维两个角度介绍

    大小:162 MBMySQL电子书

用户留言