MySQL字符集和copy_and_convert_MySQL
bitsCN.com
MySQL字符集和copy_and_convert
关于copy_and_convert
在对MySQL做业务压力测试的时候,我们在perf结果中发现 copy_and_convert 是一个耗费cpu的操作。这个函数的意思,就是在字符集之间做内容转换。
如果源和目标的字符集相同,就可以直接用memcpy,这显然比做字符集转换(按字节或字长拷贝更快,和节省cpu)
当整个系统是CPU瓶颈时,我们希望能够减少这种cpu消耗。
一次查询涉及的拷贝
如果我们执行一个简单的select语句,会涉及到两部分的内容:metadata和data。MySQL的返回包是能够“自解析”的,也就是说不仅有内容,还有描述信息。这些描述信息我们称为metadata。
在将这两部分信息返回给客户端的时候,就涉及到字符串拷贝,如果源字符集和目标字符集不同,就需要作转换。
字符集里面可以定义的部分
1、 表的字符集
比如我们创建如下的表
CREATE TABLE `t` (
`c` int(11) DEFAULT NULL,
`d` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
这就定义了这个表的字符集,要求存入数据按照gbk格式存储。在我们查询的时候,从表中读出的数据,就是我们上文说到的“源字符集”,在这里是gbk.
比如
Insert t values(2012, ‘南方很冷’);
2、连接字符集
在连接的时候我们可以在mysql客户端指定参数 mysql -default-character-set=gbk ,表示我们接收的内容希望是gbk编码,这个就是上文说的“目标字符集”。
一般我们会被建议:连接字符集和表字符集相同。
有的文章说防止乱码—-乱码倒是不会,实际的原因就是在内容拷贝时避免字符集转换计算。
本文要说的“但是”
但是即使这么做,在压力测试(或者你gdb)时,还是会发现会调用到 copy_and_convert。
原因有二:
首先,metadata部分,是固定的使用utf8,这个值可以从show variables like ‘character_set_system’;的结果看到,hardcode,配置无法修改。
其次,虽然我们定义表字符集是gbk, 但是整型字段是是Latin1存储,
#define my_charset_numeric my_charset_latin1,配置无法修改。
因此在我们上面的设置中,一次查询,在传回metadata的时候需要utf8->gbk, 返回结果中c这个字段需要latin1->gbk.
问题和建议
从上面分析知道,这存在的问题就是,无论用户怎么设置,都无法完全避免这种转换。
由于数字类型转成字符串后,使用什么字符集都占用一样的空间。
1) 在代码上最简单的修改可以如下:
将 #define my_charset_numeric my_charset_latin1 改成
#define my_charset_numeric my_charset_utf8_general_ci
这样跟metadata部分相同,然后建表和客户端都是使用utf-8。
2) 更灵活一点是把character_set_system改成可配置,然后整型存储按照用户定义的字符集。
bitsCN.com

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

如何使用Docker进行容器的性能测试和压力测试,需要具体代码示例引言容器虚拟化技术的兴起使得应用程序的部署和运行更加灵活和高效,其中最受欢迎的工具之一就是Docker。作为一种轻量级的容器化平台,Docker提供了一种方便的方式来打包、分发和运行应用程序,但是如何对容器的性能进行测试和评估,特别是在高负载情况下的压力测试,是很多人关心的问题。本文将介绍

Linux是一种开源操作系统,它提供了丰富的网络测试和压力测试工具,因此在进行网络测试和压力测试时,Linux是一个非常好的选择。在本文中,我们将介绍如何使用Linux进行网络测试和压力测试。一、网络测试网络测试是测试网络性能的过程,通常包括以下测试:带宽测试在进行网络带宽测试时,我们需要测量数据在网络中的传输速度。其中一种常用的工具是iperf,在Linu

软件压力测试是一种基本的质量保证行为,它是每个重要软件测试工作的一部分。因此压力测试是十分重要的,那么怎么进行压力测试呢?下面本篇文章就来给大家分享一个超实用压力测试神器--ab工具(apache bench),希望对大家有所帮助!

PHP是一种广泛用于Web开发的脚本语言,它被用于开发许多大型的网站和应用程序。在PHP应用程序开发的过程中,性能优化和压力测试是非常关键的,因为这将有助于你确保应用程序在实际运行过程中能够承受高负载的用户流量,而不会出现性能问题或系统崩溃。本文主要介绍一些在PHP中使用的常用压力测试工具。ApacheBenchApacheBench(ab)是一个基本的

如何使用MTR进行MySQL数据库压力测试?概述:MySQLTestRun(MTR)是MySQL官方提供的测试工具,用于测试MySQL数据库的功能和性能。除了功能测试外,MTR还可以用来进行数据库压力测试。本文将介绍如何使用MTR进行MySQL数据库压力测试,并提供一些代码示例。步骤一:安装MTR首先,我们需要安装MTR工具。MTR是MySQL源码中的

MTR:利用MySQL测试框架进行数据库压力测试的步骤引言:随着互联网的快速发展,数据库压力测试变得越来越重要。数据库压力测试旨在模拟实际使用情况下的负载,在高并发的情况下评估数据库的性能和稳定性。本文将介绍如何利用MySQL测试框架(MySQLTestRunner,简称MTR)进行数据库压力测试,并提供相应的代码示例。一、MTR简介MySQLTest

如何进行Go语言开发中的性能测试和压力测试随着互联网应用的不断发展,性能测试和压力测试成为了软件开发过程中不可或缺的一环。在Go语言开发中,我们也需要进行性能测试和压力测试来确保应用的稳定性和可靠性。本文将介绍如何进行Go语言开发中的性能测试和压力测试。一、性能测试性能测试是指通过各种手段对系统的负载性能进行评估和测试,主要包括以下几个方面:确定性能指标在进

如何进行Java开发项目的性能测试与压力测试随着互联网的不断发展,Java已经成为最为常用的开发语言之一。在进行Java开发项目时,性能测试和压力测试是非常重要的环节。通过性能测试和压力测试,可以评估系统在特定负载下的性能表现,发现和解决潜在的性能问题,确保系统具备高性能和高可用性。本文将介绍如何进行Java开发项目的性能测试和压力测试。一、性能测试性能测试
