本文主要总结关于mysql的优化(将会持续更新)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

ON DUPLICATE KEY UPDATE

事件背景

在阅读公司原来代码的过程中,我发现了这样一段代码:

$sql = "INSERT INTO {$table} ({$fields}) VALUES " . $values;
if (!empty($onDuplicate)) {$sql .= ' ON DUPLICATE KEY UPDATE '. $onDuplicate;
}

在语义的理解上,应当是索引冲突则更新原有索引数据。经过查阅资料,我总结如下:

假设业务上我们需要的就是如果存在则更新,如果不存在则新增. INSERT 中ON DUPLICATE KEY UPDATE(用redis的kv就可以很容易的实现.在MySQL中也有这样的功能)

但是这个在在使用的时候需要把关键的字段(列)设置为key ,unique key。(也就是会发生冲突的索引)

INSERT 中ON DUPLICATE KEY UPDATE的使用:

如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE。

栗子

CREATE TABLE `test_duplicate` (`id` int(11) NOT NULL AUTO_INCREMENT,`a` int(11) NOT NULL,`b` int(11) NOT NULL,`c` int(11) NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into test_duplicate (a,b,c) values(1,2,3);

假设我们有表如上,SQL列a被定义为UNIQUE,并且包含值1,则以下两段语句具有相同的效果:

mysql>INSERT INTO test_duplicate (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;  
mysql> select * from test_duplicate;
+----+---+---+---+
| id | a | b | c |
+----+---+---+---+
|  1 | 1 | 2 | 4 |
+----+---+---+---+mysql>SELECT id,a,b,c from test_duplicate where a=1;
mysql>UPDATE table SET c=c+1 WHERE id=1; SELECT id,a,b,c from test_duplicate where a=1;
+----+---+---+---+
| id | a | b | c |
+----+---+---+---+
|  1 | 1 | 2 | 5 |
+----+---+---+---+

从结果可以看出来,2段SQL都都c进行了+1操作。但是insert实际上并没有进行插入数据而是进行了更新数据。

那如果,我们表内有两个可能会产生冲突的键时,又会如何呢?

mysql> ALTER TABLE `test_duplicate` ADD UNIQUE(`b`);
mysql> INSERT INTO test_duplicate (a,b,c) VALUES (2,3,4);mysql> INSERT INTO test_duplicate (a,b,c) VALUES (1,3,4) ON DUPLICATE KEY UPDATE c=c+1;
Query OK, 2 rows affected (0.00 sec)mysql> select * from test_duplicate;
+----+---+---+---+
| id | a | b | c |
+----+---+---+---+
|  1 | 1 | 2 | 6 |
|  3 | 2 | 3 | 4 |
+----+---+---+---+

可以看出来,同时更新了两条数据 。

那假如同一行数据,我们有两个冲突的值会产生怎么样的结果呢?

mysql> INSERT INTO test_duplicate (a,b,c) VALUES (1,2,4) ON DUPLICATE KEY UPDATE c=c+1;
mysql> select * from test_duplicate;
+----+---+---+---+
| id | a | b | c |
+----+---+---+---+
|  1 | 1 | 2 | 7 |
|  3 | 2 | 3 | 4 |
+----+---+---+---+

因此,我们在设计表的时候,应该尽量避免多冲突值得存在,如果实在避免不了,我们可以使用values方法获取本次提交的值。VALUES()函数只在INSERT...UPDATE语句中有意义,其它时候会返回NULL。

mysql> INSERT INTO test_duplicate (a,b,c) VALUES (1,2,4) ON DUPLICATE KEY UPDATE c=values(c);
mysql> select * from test_duplicate;
+----+---+---+---+
| id | a | b | c |
+----+---+---+---+
|  1 | 1 | 2 | 4 |
|  3 | 2 | 3 | 4 |
+----+---+---+---+

应该一般需求都是要达到这个结果

需要注意的是,在事务中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。拿上面的实例来说,当我执行select status from t_goods where id=1 for update;后。我在另外的事务中如果再次执行select status from t_goods where id=1 for update;则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,但是如果我是在第二个事务中执行select status from t_goods where id=1;则能正常查询出数据,不会受第一个事务的影响。

关于老的数据库密码设置

刚入职的时候,我编译了自己的docker是php7环境的,然后无法支持mysql只支持mysqlnd作为pdo驱动。于是乎,错误来了

"SQLSTATE[HY000] [2000] mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). This will store a new, and more secure, hash value in mysql.user. If this user is used in other scripts executed by PHP 5.2 or earlier you might need to remove the old-passwords flag from your my.cnf file

在google遨游了很久,也没找到解决方式,然后,也尝试着装mysql然后编译PHP的时候使用mysql的头文件尝试修改mysqlnd的方式也没有成功。

网上大部分答案都需要登入mysql服务器去改my.cnf。

最后终于搞定了,将他记录下来,原来可以临时修改会话的密码长度然后重设。

mysql> SELECT user, Length(`Password`) FROM  `mysql`.`user`;
+----------------+--------------------+
| user           | Length(`Password`) |
+----------------+--------------------+
| root           |                 16 |
| root           |                  0 |
| root           |                  0 |
|                |                  0 |
|                |                  0 |
| root           |                 16 |
| test           |                 16 |
| club_star_user |                 16 |
| club_star_user |                 16 |
| wenlong11      |                 16 |
+----------------+--------------------+
mysql> SET SESSION old_passwords = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@global.old_passwords, @@session.old_passwords, Length(PASSWORD('abc'));
mysql> UPDATE mysql.user SET Password = PASSWORD('123456') WHERE user = 'xxxx';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT user, Length(`Password`) FROM  `mysql`.`user`;
+----------------+--------------------+
| user           | Length(`Password`) |
+----------------+--------------------+
| root           |                 16 |
| root           |                  0 |
| root           |                  0 |
|                |                  0 |
|                |                  0 |
| root           |                 16 |
| test           |                 16 |
| club_star_user |                 16 |
| club_star_user |                 16 |
| wenlong11      |                 41 |
+----------------+--------------------+

可以观察到 密码长度终于变成41的新版的长度了

order by 排序不准

mysql排序 假如对很多值相等的值进行order 分页 会产生乱序 导致数据重复

select * from where a = 3 and b = 5 order by c descselect * from where a = 3 and b =5 order by c desc, d desc

解决方式: 1、尽量不要使用这种字段排序 2、如果业务需求,将其修改成多种混合 如 order field desc => order field desc, uniqueField desc 确保结果不会混乱

MySQL Explain

示例: explain select * from tablename;

将会得出结果查询详情,而不是结果集

expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra

force index

在某些情况下,mysql推荐的索引并不是我们最想用的业务(根据业务需求)

这个时候,我们可以将自己确定的索引进行设置,保证本条SQL强制走索引

select * from $table_name force index(index_name) where condition  limit number

测试性能比较

8000W 数据,不用force index 200s都未查询完毕

加了之后,1S左右完成

执行explain,发现这个sql扫描了8000W条记录到磁盘上。然后再进行筛选。type=index说明整个索引树都被扫描了,效果显然不理想。

ignore index

对应的,在某些情况下我们确定了不需要某个索引

这个时候,我们可以将此索引忽略,保证本条SQL不遍历这个索引

转载于:https://my.oschina.net/lwl1989/blog/1927713

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CS Academy Gcd Rebuild

题目链接:https://csacademy.com/contest/archive/task/gcd-rebuild/statement/ 题目大意:给出一个N*M的矩阵,其中第i行j列表示gcd(a[i], b[j]),现在不知道数组a,b,给出这个矩阵,求a&#xff0c…

ASP.NET Core 在 IIS 下的两种部署模式

KestrelServer最大的优势体现在它的跨平台的能力,如果ASP.NET CORE应用只需要部署在Windows环境下,IIS也是不错的选择。ASP.NET CORE应用针对IIS具有两种部署模式,它们都依赖于一个IIS针对ASP.NET CORE Core的扩展模块。一、ASP.NET CORE Cor…

navicat连接远程mysql

环境介绍: 这里,我连接的是阿里云的服务器,自己搭的环境,用的是mysql 5.7一 首先第一步,需要进入远程服务器的mysql,更改host访问权限 然后,将root允许访问的host 改为%(任何ip地址都可以访问) 注: 原来是只允许本地访问二 本地用navicat连接远程mysql 1. 常规部分填写2. SSH部…

2018-08-15期 HBase命令行使用案例

1、进入hbase命令行[roothadoop-server01 bin]# hbase shell2、命令行帮助COMMAND GROUPS:Group name: generalCommands: status, table_help, version, whoamiGroup name: ddlCommands: alter, alter_async, alter_status, create, describe, disable, disable_all, drop, dro…

面向对象五大设计原则

最近在看七牛云许式伟的架构课, 重温了面向对象五大设计原则(SOLID),扣理论文字找出处。(当然许老板是不可能深聊这么低级的内容,🤡)注意区分设计原则和设计模式。设计原则更为抽象和泛化;设计模式也是抽象…

python函数式编程-匿名函数

>>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) [1, 4, 9, 16, 25, 36, 49, 64, 81] 关键字lambda表示匿名函数,冒号前面的x表示函数参数。 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表…

bean初始化、注销

关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过PostConstruct 和 PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二种是:通过 在xml中定义init-method 和 destory-method方法 第三种是:…

谷歌F12调试公众号时,让鼠标显示出来

yi 环境介绍: win10 , 谷歌浏览器yii 概述: 在项目中,需要调试公众号,本地环境搭好之后,在谷歌浏览时,发现移动到公众号区域,鼠标居然不见了,这让我怎么操作?各种操作可谓是日了狗了,非常麻烦yiii 调试时鼠标不见的解决办法: 网上各种说法众说纷纭,这里,我给出本人认为最恰当简…

利用bootstrap插件设置时间

$("#"id_rand" .shijian-input").each(function () { $(this).datetimepicker({ lang:"ch", //语言选择中文 注:旧版本 新版方法:$.datetimepicker.setLocale(ch); format: "hh : ii", /…

C# 编写的 64位操作系统 -MOOS

MOOSMOOS ( My Own Operating System )是一个使用.NET Native AOT技术编译的C# 64位操作系统。项目地址:https://github.com/nifanfa/MOOS编译关于编译MOOS的信息,请阅读 编译维基页面:https://github.com/nifanfa/MOOS/wiki/。编译要求VMwar…

js获取屏幕宽高和下拉加载更多

document.body.clientWidth > BODY对象宽度 document.body.clientHeight > BODY对象高度 document.documentElement.clientWidth > 可见区域宽度 document.documentElement.clientHeight > 可见区域高度 网页可见区域宽: document.body.clientWid…

X5开发中buttongrounp对应contents组件切换时速度快点无效

官方提供的解决办法是:http://docs.wex5.com/wex5-ui-question-list-2084/ 原文如下:【问题】buttongrounp中的button按钮全是代码动态生成,对应的contents中的content也是代码动态生成。发现在快读点击button的时候,content就会死…

JAVA语言基础-面向对象(IO:IO字符流、递归)

2019独角兽企业重金招聘Python工程师标准>>> 21.01_IO流(字符流FileReader) 1.字符流是什么 字符流是可以直接读写字符的IO流字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出.2.FileReader FileReader类的read()方法…

windows下, nginx 提示错误 No input file specified

一 环境介绍: win10, LNMP 二 错误描述: 访问网站时,提示"No input file specified"错误. 排错阶段: 1. 查看nginx access日志 (access.log) 发现提示404 错误 2. 分析原因: 这时,在同目录下创建一个txt文件,访问就可以正常输出了 这说明 现在nginx 访问php 没…

Ubuntu20.04+docker+jenkins+飞书实现自动化发布

一、从0-1一点一滴实现如何本地提交代码到gitlab然后实现前后端自动发布1.更新apt包索引sudo apt-get update2.安装必备的软件包以允许apt通过https使用存储库sudo apt-get install ca-certificates curl gnupg lsb-release3.添加Docker官方版本的GPG密钥sudo mkdir -p /etc/ap…

一个Demo让你掌握Android所有控件

一个Demo让你掌握Android所有控件 原文:一个Demo让你掌握Android所有控件本文是转载收藏,侵删,出处:"安卓巴士" 下面给出实现各个组件的源代码: 1.下拉框实现--Spinner [java] view plaincopyprint?package com.cellcom; import java.util.ArrayList;…

九妹带你走向 架构师

迈向系统架构师编者按:系统架构师是许多程序员的梦想职业。今天的你也许已经掌握了各种开发工具,并且能够使用各种平台进行开发,但作为一个架构师的要求,也许还有很长的道路。邢波涛先生在LAMP架构上的造诣,让我邀请他…

WPF 使用 DrawingContext 绘制温度计

WPF 使用 DrawingContext 绘制温度计控件名:Thermometer作者: WPFDevelopersOrg原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40;Visual Studio 2022;项目使用 MIT 开源许可协议&#xff…

MAVEN简介之——settings.xml

概述 Maven的settings.xml配置了Maven执行的方式,像pom.xml一样,但是它是一个通用的配置,不能绑定到任何特殊的项目。它通常包括本地仓库地址,远程仓库服务,认证信息等。 settings.xml存在于两个位置: mave…

装win10系统

一、使用U盘介质安装win10系统(官方方式) 官方安装工具下载地址:https://www.microsoft.com/zh-cn/software-download/windows10 1、进入官方安装工具下载页面,点击立即下载工具,下载安装工具。2、下载完成后&#xff…