精华内容
下载资源
问答
  • 业务高峰期,生产环境的 MySQL 压力太大,没法正常响应,需要短期内、临时性提升一些性能。 如果是无损方案的话,肯定不需要等到这个时候才上场。今天我们就来聊聊这些临时方案,并着重说一说它们可能存在的风险。...

    业务高峰期,生产环境的 MySQL 压力太大,没法正常响应,需要短期内、临时性地提升一些性能。

    如果是无损方案的话,肯定不需要等到这个时候才上场。今天我们就来聊聊这些临时方案,并着重说一说它们可能存在的风险。

    短连接风暴

    正常的短连接模式就是连接到数据库后,执行很少的 SQL 语句就断开,下次需要的时候再重连。如果使用的是短连接,在业务高峰期的时候,就可能出现连接数突然暴涨的情况。

    MySQL 建立连接的过程,成本是很高的。除了正常的网络连接三次握手外,还需要做登录权限判断和获得这个连接的数据读写权限。

    在数据库压力比较小的时候,这些额外的成本并不明显。

    但是,短连接模型存在一个风险,就是一旦数据库处理得慢一些,连接数就会暴涨。max_connections 参数,用来控制一个 MySQL 实例同时存在的连接数的上限,超过这个值,系统就会拒绝接下来的连接请求,并报错提示“Too many connections”。对于被拒绝连接的请求来说,从业务角度看就是数据库不可用。

    在机器负载比较高的时候,处理现有请求的时间变长,每个连接保持的时间也更长。这时,再有新建连接的话,就可能会超过 max_connections 的限制。

    碰到这种情况时,一个比较自然的想法,就是调高 max_connections 的值。但这样做是有风险的。因为设计 max_connections 这个参数的目的是想保护 MySQL,如果我们把它改得太大,让更多的连接都可以进来,那么系统的负载可能会进一步加大,大量的资源耗费在权限验证等逻辑上,结果可能是适得其反,已经连接的线程拿不到 CPU 资源去执行业务的 SQL 请求。

    那么这种情况下,你还有没有别的建议呢?我这里还有两种方法,但要注意,这些方法都是有损的。

    第一种方法:先处理掉那些占着连接但是不工作的线程。

    max_connections 的计算,不是看谁在 running,是只要连着就占用一个计数位置。对于那些不需要保持的连接,我们可以通过 kill connection 主动踢掉。这个行为跟事先设置 wait_timeout 的效果是一样的。设置 wait_timeout 参数表示的是,一个线程空闲 wait_timeout 这么多秒之后,就会被 MySQL 直接断开连接。

    但是需要注意,在 show processlist 的结果里,踢掉显示为 sleep 的线程,可能是有损的。我们来看下面这个例子。

    在这里插入图片描述
    在上面这个例子里,如果断开 session A 的连接,因为这时候 session A 还没有提交,所以 MySQL 只能按照回滚事务来处理;而断开 session B 的连接,就没什么大影响。所以,如果按照优先级来说,你应该优先断开像 session B 这样的事务外空闲的连接。

    但是,怎么判断哪些是事务外空闲的呢?session C 在 T 时刻之后的 30 秒执行 show processlist,看到的结果是这样的

    在这里插入图片描述
    图中 id=4 和 id=5 的两个会话都是 Sleep 状态。而要看事务具体状态的话,你可以查 information_schema 库的 innodb_trx 表。

    在这里插入图片描述
    这个结果里,trx_mysql_thread_id=4,表示 id=4 的线程还处在事务中。

    因此,如果是连接数过多,你可以优先断开事务外空闲太久的连接;如果这样还不够,再考虑断开事务内空闲太久的连接。

    从服务端断开连接使用的是 kill connection + id 的命令, 一个客户端处于 sleep 状态时,它的连接被服务端主动断开后,这个客户端并不会马上知道。直到客户端在发起下一个请求的时候,才会收到这样的报错“ERROR 2013 (HY000): Lost connection to MySQL server during query”。

    从数据库端主动断开连接可能是有损的,尤其是有的应用端收到这个错误后,不重新连接,而是直接用这个已经不能用的句柄重试查询。这会导致从应用端看上去,“MySQL 一直没恢复”。

    所以,如果你是一个支持业务的 DBA,不要假设所有的应用代码都会被正确地处理。即使只是一个断开连接的操作,也要确保通知到业务开发团队。

    第二种方法:减少连接过程的消耗。

    有的业务代码会在短时间内先大量申请数据库连接做备用,如果现在数据库确认是被连接行为打挂了,那么一种可能的做法,是让数据库跳过权限验证阶段。

    跳过权限验证的方法是:重启数据库,并使用–skip-grant-tables 参数启动。这样,整个 MySQL 会跳过所有的权限验证阶段,包括连接过程和语句执行过程在内。

    但是,这种方法特别符合我们标题里说的“饮鸩止渴”,风险极高,是我特别不建议使用的方案。尤其你的库外网可访问的话,就更不能这么做了。

    在 MySQL 8.0 版本里,如果你启用–skip-grant-tables 参数,MySQL 会默认把 --skip-networking 参数打开,表示这时候数据库只能被本地的客户端连接。可见,MySQL 官方对 skip-grant-tables 这个参数的安全问题也很重视。

    除了短连接数暴增可能会带来性能问题外,实际上,我们在线上碰到更多的是查询或者更新语句导致的性能问题。其中,查询问题比较典型的有两类,一类是由新出现的慢查询导致的,一类是由 QPS(每秒查询数)突增导致的。

    慢查询性能问题

    在 MySQL 中,会引发性能问题的慢查询,大体有以下三种可能:

    • 索引没有设计好;
    • SQL语句没写好
    • MySQL 选错了索引。

    接下来,我们就具体分析一下这三种可能,以及对应的解决方案。

    索引没有设计好

    这种场景一般就是通过紧急创建索引来解决。MySQL 5.6 版本以后,创建索引都支持 Online DDL 了,对于那种高峰期数据库已经被这个语句打挂了的情况,最高效的做法就是直接执行 alter table 语句。

    比较理想的是能够在备库先执行。假设你现在的服务是一主一备,主库 A、备库 B,这个方案的大致流程是这样的:

    • 在备库 B 上执行 set sql_log_bin=off,也就是不写 binlog,然后执行 alter table 语句加上索引;
    • 执行主备切换;
    • 这时候主库是 B,备库是 A。在 A 上执行 set sql_log_bin=off,然后执行 alter table 语句加上索引。

    这是一个“古老”的 DDL 方案。平时在做变更的时候,你应该考虑类似 gh-ost 这样的方案,更加稳妥。但是在需要紧急处理时,上面这个方案的效率是最高的。

    SQL 语句没写好

    这时,我们可以通过改写 SQL 语句来处理。MySQL 5.7 提供了 query_rewrite 功能,可以把输入的一种语句改写成另外一种模式。

    比如,语句被错误地写成了 select * from t where id + 1 = 10000,你可以通过下面的方式,增加一个语句改写规则。

    
    mysql> insert into query_rewrite.rewrite_rules(pattern, replacement, pattern_database) values ("select * from t where id + 1 = ?", "select * from t where id = ? - 1", "db1");
    
    call query_rewrite.flush_rewrite_rules();
    

    这里,call query_rewrite.flush_rewrite_rules() 这个存储过程,是让插入的新规则生效,也就是我们说的“查询重写”。你可以用图 4 中的方法来确认改写规则是否生效。

    在这里插入图片描述

    MySQL 选错索引

    这时候,应急方案就是给这个语句加上 force index。

    同样地,使用查询重写功能,给原来的语句加上 force index,也可以解决这个问题。

    上面我和你讨论的由慢查询导致性能问题的三种可能情况,实际上出现最多的是前两种,即:索引没设计好和语句没写好。而这两种情况,恰恰是完全可以避免的。比如,通过下面这个过程,我们就可以预先发现问题。

    • 上线前,在测试环境,把慢查询日志(slow log)打开,并且把 long_query_time 设置成 0,确保每个语句都会被记录入慢查询日志;
    • 在测试表里插入模拟线上的数据,做一遍回归测试;
    • 观察慢查询日志里每类语句的输出,特别留意 Rows_examined 字段是否与预期一致。

    不要吝啬这段花在上线前的“额外”时间,因为这会帮你省下很多故障复盘的时间。

    如果新增的 SQL 语句不多,手动跑一下就可以。而如果是新项目的话,或者是修改了原有项目的 表结构设计,全量回归测试都是必要的。这时候,你需要工具帮你检查所有的 SQL 语句的返回结果。比如,你可以使用开源工具 pt-query-digest(https://www.percona.com/doc/percona-toolkit/3.0/pt-query-digest.html)。

    QPS 突增问题

    有时候由于业务突然出现高峰,或者应用程序 bug,导致某个语句的 QPS 突然暴涨,也可能导致 MySQL 压力过大,影响服务。

    我之前碰到过一类情况,是由一个新功能的 bug 导致的。当然,最理想的情况是让业务把这个功能下掉,服务自然就会恢复。

    而下掉一个功能,如果从数据库端处理的话,对应于不同的背景,有不同的方法可用。我这里再和你展开说明一下。

    • 一种是由全新业务的 bug 导致的。假设你的 DB 运维是比较规范的,也就是说白名单是一个个加的。这种情况下,如果你能够确定业务方会下掉这个功能,只是时间上没那么快,那么就可以从数据库端直接把白名单去掉。
    • 如果这个新功能使用的是单独的数据库用户,可以用管理员账号把这个用户删掉,然后断开现有连接。这样,这个新功能的连接不成功,由它引发的 QPS 就会变成 0。
    • 如果这个新增的功能跟主体功能是部署在一起的,那么我们只能通过处理语句来限制。这时,我们可以使用上面提到的查询重写功能,把压力最大的 SQL 语句直接重写成"select 1"返回。

    当然,这个操作的风险很高,需要你特别细致。它可能存在两个副作用:

    • 如果别的功能里面也用到了这个 SQL 语句模板,会有误伤;
    • 很多业务并不是靠这一个语句就能完成逻辑的,所以如果单独把这一个语句以 select 1 的结果返回的话,可能会导致后面的业务逻辑一起失败。

    所以,方案 3 是用于止血的,跟前面提到的去掉权限验证一样,应该是你所有选项里优先级最低的一个方案。

    同时你会发现,其实方案 1 和 2 都要依赖于规范的运维体系:虚拟化、白名单机制、业务账号分离。由此可见,更多的准备,往往意味着更稳定的系统。

    思考题

    你是否碰到过,在业务高峰期需要临时救火的场景?你又是怎么处理的呢?

    展开全文
  • 当我们在网络上找到有用的资料时,相信很多人第...本文中来分享几个方法,帮你永久保存网页1.直接保存网页到电脑想要保存网页在电脑上查看,浏览器自己就提供了一个很好的网页保存工具打开Chrome的扩展来右侧的按钮...

    当我们在网络上找到有用的资料时,相信很多人第一个想到的就是添加到浏览器的收藏夹,因为不管是收藏还是以后查看都非常地方便,但是有时一些网页会因为网站关闭、文章删除、404等各种原因无法访问,导致我们之前收藏的文章失效,那么如何避免这种情况呢?本文中来分享几个方法,帮你永久保存网页

    1.直接保存网页到电脑

    想要保存网页在电脑上查看,浏览器自己就提供了一个很好的网页保存工具

    打开Chrome的扩展来右侧的按钮,选择 更多工具 – 网页另存为,或者直接按快捷键 Ctrl + S ,就可以打开浏览器的网页保存窗口,将网页的文件全部保存到本地,包括网页内容、图片、代码文件等全部都会拷贝下来

    不过,默认情况下当你保存网页时,每个网页都会带有一个文件夹,管理起来不够方便

    此时,你可以做一个操作,将保存类型设置为 .mhtml 格式的单个文件,这样就可以将网页中的所有内容合并成一个文件了,可以更方便地存储和使用

    2.使用笔记软件剪藏

    现在很多的云笔记软件都提供了剪藏功能,可以直接把网页收藏到自己的云笔记中,可供随时访问,我们可以用它的这个特性永久保存网页

    支持剪藏的云笔记有很多,常见的比如 Evernote、OneNote、Notion、Bear 等,都提供了对应的浏览器扩展,可以快速保存网页中的内容,因为每个笔记都有自己的保存方法,这里就不再多说,具体的可以查看相关文档

    3.用网页收藏工具存档网页

    如果你经常使用第三方的工具收藏网页,一些软件也可以将网页内容存储在自己的服务器上,比如Pocket、Raindrop等,当你收藏以后它会主动抓取你收藏的网页正文,将内容存放在自己的服务器上,即使原网页失效,仍然可以在工具中查看内容,不过需要注意一点是网页自动存档一般为付费功能

    4.发送到自己的邮件

    对于经常阅读 Newsletter 的人来说,很多人喜欢将内容存储到自己的邮箱中,可以随时阅读,如果你也经常用邮件阅读的话,EmailThis 可能是一个很适合你的工具,它可以把你想要阅读的文章以邮件的形式发送到你的邮箱,让你可以随时在邮件客户端中阅读保存的文章

    5.保存网页为长截图

    如果你想要完整地保存网站上所有的内容格式,也可以使用长截图的方式来截取网页

    使用截图扩展截取网页

    浏览器的截图扩展有很多,比如Chrome商店的一款截图扩展 FireShot,它就是专门制作网页长截图的,安装好扩展后,点击捕捉整个页面,FireShot 就会自动滚动页面并截取网页,软件会自动忽略页面中的固定元素,保证内容完整显示

    截图完成后,你可以选择存储为图片或PDF格式,还可以发送到Gmail、复制剪贴板等操作,定制性很高,另外,还有一些截图扩展还支持保存到网盘、分享、标注等功能,可以进一步提高工作的效率

    使用支持滚动截图的截图软件

    如果你只是偶尔需要保存几个网页,又不想安装浏览器扩展,也可以使用支持滚动截图的截图软件来截取网页,比如使用QQ自带的截图、Xnip、CleanShot等都提供了滚动截图功能

    只需要在截图时滚动鼠标,它会自动为你拼接出一个长网页,你可以截取任意长度的网页,不过有一个缺点是对于特别长的网页,这种滚动截图的方式速度太慢,而且需要不断拖动滚轮,所以并不适合重度用户使用

    好了,以上就是本文介绍的几个网页保存的方法,你可以根据自己的实际需求进行选择

    展开全文
  • Mysql临时表空间详解

    2021-01-18 20:46:36
    一、临时表空间介绍1、官方文档Non-compressed, user-created temporary tables and on-disk internal temporary tables are created in a shared temporary tablespaceThe innodb_temp_data_file_path ...

    一、临时表空间介绍

    1、官方文档

    Non-compressed, user-created temporary tables and on-disk internal temporary tables are created in a shared temporary tablespace

    The innodb_temp_data_file_path configuration option defines the relative path, name, size, and attributes for temporary tablespace data files. If no value is specified for innodb_temp_data_file_path, the default behavior is to create an auto-extending data file named ibtmp1 in the innodb_data_home_dir directory that is slightly larger than 12MB.

    Compressed temporary tables, which are temporary tables created using the ROW_FORMAT=COMPRESSED attribute, are created in file-per-table tablespaces in the temporary file directory.

    The temporary tablespace is removed on normal shutdown or on an aborted initialization, and is recreated each time the server is started . The temporary tablespace receives a dynamically generated space ID when it is created. Startup is refused if the temporary tablespace cannot be created. The temporary tablespace is not removed if the server halts unexpectedly. In this case, a database administrator can remove the temporary tablespace manually or restart the server, which removes and recreates the temporary tablespace automatically.

    2、翻译

    用户创建的非压缩临时表和磁盘上的内部临时表是在共享临时表空间中创建的。

    innodb_temp_data_file_path配置选项定义临时表空间数据文件的相对路径、名称、大小和属性。如果没有为innodb_temp_data_file_path指定值,默认行为是在innodb_data_home_dir目录中创建一个名为ibtmp1的自动扩展数据文件,该文件略大于12MB。

    压缩临时表是使用ROW_FORMAT = COMPRESSED属性创建的临时表,它们是在临时文件目录中的每表文件表空间中创建的。

    用户创建的临时表和磁盘内部临时表创建于共享临时表空间中。

    innodb_temp_data_file_path配置选项定义临时表空间数据文件的相对路径,名称,大小和属性。 如果没有为innodb_temp_data_file_path指定值,则默认行为是在innodb_data_home_dir目录中创建一个稍大于12MB的名为 ibtmp1 的自动扩展数据文件。

    临时表空间在正常关闭或中止初始化时被删除,并在每次启动服务器时重新创建 。 临时表空间在创建时会收到动态生成的空间ID。 如果无法创建临时表空间,则拒绝启动。 如果服务器意外停止,则不会删除临时表空间。 在这种情况下,数据库管理员可以手动删除临时表空间或重新启动服务器,从而自动删除并重新创建临时表空间。

    3、解释

    MySQL 5.7对于InnoDB存储引擎的临时表空间做了优化。在MySQL 5.7之前,INNODB引擎的临时表都保存在ibdata里面,而ibdata的贪婪式磁盘占用导致临时表的创建与删除对其他正常表产生非常大的性能影响。在MySQL5.7中,对于临时表做了下面两个重要方面的优化:

    MySQL 5.7 把临时表的数据以及回滚信息(仅限于未压缩表)从共享表空间里面剥离出来,形成自己单独的表空间,参数为innodb_temp_data_file_path。

    二、临时表与临时文件

    1、临时表

    临时表可以分为磁盘临时表和内存临时表,而临时文件,只会存在于磁盘上,不会存在于内存中。具体来说,临时表的内存形态有Memory引擎和Temptable引擎,主要区别是对字符类型(varchar, blob,text类型)的存储方式,前者不管实际字符多少,都是用定长的空间存储,后者会用变长的空间存储,这样提高了内存中的存储效率,有更多的数据可以放在内存中处理而不是转换成磁盘临时表。Memory引擎从早期的5.6就可以使用,Temptable是8.0引入的新的引擎。另外一方面,磁盘临时表也有三种形态,一种是MyISAM表,一种是InnoDB临时表,另外一种是Temptable的文件map表。其中最后一种方式,是8.0提供的。

    在5.6以及以前的版本,磁盘临时表都是放在数据库配置的临时目录,磁盘临时表的undolog都是与普通表的undo放在一起(注意由于磁盘临时表在数据库重启后就被删除了,不需要redolog通过奔溃恢复来保证事务的完整性,所以不需要写redolog,但是undolog还是需要的,因为需要支持回滚)。

    在MySQL 5.7后,磁盘临时表的数据和undo都被独立出来,放在一个单独的表空间ibtmp1里面。之所以把临时表独立出来,主要是为了减少创建删除表时维护元数据的开销。

    在MySQL 8.0后,磁盘临时表的数据单独放在Session临时表空间池(#innodb_temp目录下的ibt文件)里面,临时表的undo放在global的表空间ibtmp1里面。另外一个大的改进是,8.0的磁盘临时表数据占用的空间在连接断开后,就能释放给操作系统,而5.7的版本中需要重启才能释放。

    目前有以下两种情况会用到临时表:

    1)用户显式创建临时表

    这种是用户通过显式的执行命令create temporary table创建的表,引擎的类型要么显式指定,要么使用默认配置的值(default_tmp_storage_engine)。内存使用就遵循指定引擎的内存管理方式,比如InnoDB的表会先缓存在Buffer Pool中,然后通过刷脏线程写回磁盘文件。

    在5.6中,磁盘临时表位于tmpdir下,文件名类似#sql4d2b_8_0.ibd,其中#sql是固定的前缀,4d2b是进程号的十六进制表示,8是MySQL线程号的十六进制表示(show processlist中的id),0是每个连接从0开始的递增值,ibd是innodb的磁盘临时表(通过参数default_tmp_storage_engine控制)。在5.6中,磁盘临时表创建好后,对应的frm以及引擎文件就在tmpdir下创建完毕,可以通过文件系统ls命令查看到。在连接关闭后,相应文件自动删除。因此,我们如果在5.6的tmpdir里面看到很多类似格式文件名,可以通过文件名来判断是哪个进程,哪个连接使用的临时表,这个技巧在排查tmpdir目录占用过多空间的问题时,尤其适用。用户显式创建的这种临时表,在连接释放的时候,会自动释放并把空间释放回操作系统。临时表的undolog存在undo表空间中,与普通表的undo放在一起。有了undo回滚段,用户创建的这种临时表也能支持回滚了。

    在5.7中,临时磁盘表位于ibtmp文件中,ibtmp文件位置及大小控制方式由参数innodb_temp_data_file_path控制。显式创建的表的数据和undo都在ibtmp里面。用户连接断开后,临时表会释放,但是仅仅是在ibtmp文件里面标记一下,空间是不会释放回操作系统的。如果要释放空间,需要重启数据库。另外,需要注意的一点是,5.6可以在tmpdir下直接看到创建的文件,但是5.7是创建在ibtmp这个表空间里面,因此是看不到具体的表文件的。如果需要查看,则需要查看INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO这个表,里面有一列name,这里可以看到表名。命名规格与5.6的类似,因此也可以快速找到占用空间大的连接。

    在8.0中,临时表的数据和undo被进一步分开,数据是存放在ibt文件中(由参数innodb_temp_tablespaces_dir控制),undo依然存放在ibtmp文件中(依然由参数innodb_temp_data_file_path控制)。存放ibt文件的叫做Session临时表空间,存放undo的ibtmp叫做Global临时表空间。这里介绍一下这个存放数据的Session临时表空间。Session临时表空间,在磁盘上的表现是一组以ibt文件组成的文件池。启动的时候,数据库会在配置的目录下重新创建,关闭数据库的时候删除。启动的时候,默认会创建10个ibt文件,每个连接最多使用两个,一个给用户创建的临时表用,另外一个给下文描述的优化器创建的隐式临时表使用。当然只有在需要临时表的时候,才会创建,如果不需要,则不会占用ibt文件。当10个ibt都被使用完后,数据库会继续创建,最多创建四十万个。当连接释放时候,会自动把这个连接使用的ibt文件给释放,同时回收空间。如果要回收Global临时表空间,依然需要重启。但是由于已经把存放数据的文件分离出来,且其支持动态回收(即连接断开即释放空间),所以5.7上困扰大家多时的空间占用问题,已经得到了很好的缓解。当然,还是有优化空间的,例如,空间需要在连接断开后,才能释放,而理论上,很多空间在某些SQL(如用户drop了某个显式创建的临时表)执行后,即可以释放。另外,如果需要查看表名,依然查看INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO这个表。需要注意的是,8.0上,显式临时表不能是压缩表,而5.6和5.7可以。

    2)优化器隐式创建临时表

    这种临时表,是数据库为了辅助某些复杂SQL的执行而创建的辅助表,是否需要临时表,一般都是由优化器决定。与用户显式创建的临时表直接创建磁盘文件不同,如果需要优化器觉得SQL需要临时表辅助,会先使用内存临时表,如果超过配置的内存(min(tmp_table_size, max_heap_table_siz)),就会转化成磁盘临时表,这种磁盘临时表就类似用户显式创建的,引擎类型通过参数internal_tmp_disk_storage_engine控制。一般稍微复杂一点的查询,包括且不限于order by, group by, distinct等,都会用到这种隐式创建的临时表。用户可以通过explain命令,在Extra列中,看是否有Using temporary这样的字样,如果有,就肯定要用临时表。

    在5.6中,隐式临时表依然在tmpdir下,在复杂SQL执行的过程中,就能看到这临时表,一旦执行结束,就被删除。值得注意的是,5.6中,这种隐式创建的临时表,只能用MyISAM引擎,即没有internal_tmp_disk_storage_engine这个参数可以控制。所以,当我们的系统中只有innodb表时,也会看到MyISAM的某些指标在变动,这种情况下,一般都是隐式临时表的原因。

    在5.7中,隐式临时表是创建在ibtmp文件中的,SQL结束后,会标记删除,但是空间依然不会返还给操作系统,如果需要返还,则需要重启数据库。另外,5.7支持参数internal_tmp_disk_storage_engine,用户可以选择InnoDB或者MYISAM表作为磁盘临时表。

    在8.0中,隐式临时表是创建在Session临时表空间中的,即与用户显式创建的临时表的数据放在一起。如果一个连接第一次需要隐式临时表,那么数据库会从ibt文件构成的池子中取出一个给这个连接使用,直到连接释放。上文中,我们也提到过,在8.0中,用户显式创建的临时表也会从池子中分配一个ibt来使用,每个连接最多使用两个ibt文件用来存储临时表。我们可以查询INFORMATION_SCHEMA.INNODB_SESSION_TEMP_TABLESPACES来确定ibt文件的去向。这个表中,每个ibt文件是一行,当前系统中有几个ibt文件就有几行。有一列叫做ID,如果此列为0,表示此ibt没有被使用,如果非0,表示被此ID的连接在用,比如ID为8,则表示process_id为8的连接在用这个ibt文件。另外,还有一列purpose,值为INTRINSIC表示是隐式临时表在用这个ibt,USER则表示是显示临时表在用。此外,还有一列size,表示当前的大小。用户可以查询这个表来确定整个数据库临时表的使用情况,十分方便。

    在5.6和5.7中,内存临时表只能使用Memory引擎,到了8.0,多了一种Temptable引擎的选择。Temptable在存储格式有采用了变长存储,可以节省存储空间,进一步提高内存使用率,减少转换成磁盘临时表的次数。如果设置的磁盘临时表是InnoDB或者MYISAM,则需要一个转换拷贝的消耗。为了尽可能减少消耗,Temptable提出了一种overflow机制,即如果内存临时表超过配置大小,则使用磁盘空间map的方式,即打开一个文件,然后删除,留一个句柄进行读写操作。读写文件格式和内存中格式一样,这样就略过了转换这一步,进一步提高性能。注意,这个功能是在还没发布的8.0.16版本中才有的,因为还看不到代码,只能通过文档猜测其实现。在8.0.16中,参数internal_tmp_disk_storage_engine已经被去掉,磁盘临时表只能使用InnoDB形式或者TempTable的这种overflow形式。从文档中,我们似乎看出官方比较推荐使用TempTable这个新的引擎。具体性能提升情况,还需要等代码发布后,测试过才能得出结论。

    2)临时文件

    相比临时表,临时文件对大家可能更加陌生,临时文件更多的被使用在缓存数据,排序数据的场景中。一般情况下,被缓存或者排序的数据,首先放在内存中,如果内存放不下,才会使用磁盘临时文件的方式。临时文件的使用方式与一般的表也不太一样,一般的表创建完后,就开始读写数据,使用完后,才把文件删除,但是临时文件的使用方式不一样,在创建完后(使用mkstemp系统函数),马上调用unlink删除文件,但是不close文件,后续使用原来的句柄操作文件。这样的好处是,当进程异常crash,不会有临时文件因为没被删除而残留,但是坏处也是明显的,我们在文件系统上使用ls命令就看不到这个文件,需要使用lsof +L1来查看这种deleted属性的文件。

    目前,我们主要在一下场景使用临时文件:

    1)DDL中的临时文件

    在做online DDL的过程中,很多操作需要对原表进行重建,对表重建前,需要对各种二级索引排序,而大量数据的排序,不太可能在内存中完成,需要依赖外部排序算法,MySQL使用了归并排序。这个过程中就需要创建临时文件。一般需要的空间大小与原表差不多。但是在使用完之后,会马上清理,所以在做DDL的时候,需要保留出足够的空间。用户可以通过指定innodb_tmpdir来指定这种排序文件的路径。这个参数可以动态修改,一般把他设置在有足够磁盘空间的路径上。临时文件的名字一般是类似ibXXXXXX,其中ib是固定前缀,XXXXXX是大小写字母以及数字的随机组合。

    在做online DDL中,我们是允许用户对原表做DML操作的,即增删改查。我们不能直接插入原表中,因此需要一个地方记录对原表的修改操作,在DDL结束后,再应用在新表上。这个记录的地方就是online log,当然如果改动少的话,直接存在内存里(参数innodb_sort_buffer_size可控制,同时这个参数也控制online log每个读写块的大小)面即可。这个onlinelog也是用临时文件存,创建在innodb_tmpdir,最大大小为参数innodb_online_alter_log_max_size控制,如果超过这个大小了,DDL就会失败。临时文件的名字也类似上述的排序临时文件的名字。

    在online DDL的最后阶段,需要把排序完的文件和中途产生的DML全都应用到一个中间文件上,中间文件文件名类似#sql-ib53-522550444.ibd,其中#sql-ib是固定的前缀,53是InnoDB层的table id,522550444是随机生成的数字。同时,在server层也会生成一个frm文件(8.0中没有),文件名类似#sql-4d2b_2a.frm,其中#sql是固定前缀,4d2b是进程号的十六进制表示,2a是线程号的十六进制表示(show processlist中的id)。因此我们也可以通过这个命名规则来找到哪个线程在做DDL。这里需要注意一点,这里说的中间文件,其实算是一个临时表,并不是上文说中临时文件,这些中间文件可以通过ls来查看。当在DDL中的最后一步,会把这两个临时文件命名回原来的表名。正因为这个特性,所以当数据库中途crash的时候,可能会在磁盘上留下残余无用的文件。遇到这种情况,可以先把frm文件重命名成与ibd文件一样的名字,然后使用DROP TABLE#mysql50##sql-ib53-522550444`来清理残余的文件。注意,如果不用drop命令,直接删除ibd文件,可能会导致数据字典里面依然有残余的信息,做法不太优雅。当然,在8.0中,由于使用了原子的数据字典,就不会出现这种残余文件了。

    2)BinLog中的缓存操作

    BinLog只有在事务提交的时候才会写入到文件中,在没提交前,会先放在内存中(由参数binlog_cache_size控制),如果内存放慢了,就会创建临时文件,使用方法也是先通过mkstemp创建,然后直接unlink,留一个句柄读写。临时文件名类似MLXXXXXX,其中ML是固定前缀,XXXXXX是大小写字母以及数字的随机组合。单个事务的BinLog太大,可能会导致整个BinLog的大小也过大,从而影响同步,因此我们需要尽可能控制事务大小。

    3)优化创建的临时文件

    有些操作,除了在引擎层需要依赖隐式临时表来辅助复杂SQL的计算,在Server层,也会创建临时文件来辅助,比如order by操作,会调用filesort函数。这个函数也会先使用内存(sort_buffer_size)排序,如果不够,就会创建一个临时文件,辅助排序。文件名类似MYXXXXXX,其中MY是固定前缀,XXXXXX是大小写字母以及数字的随机组合。

    4)Load data中用的临时文件

    在BinLog复制中,如果在主库上使用了Load Data命令,即从文件中导数据,数据库会把整个文件写入到RelayLog中,然后传到备库,备库解析RelayLog,从中抽取出对应的Load文件,然后在备库上应用。备库上这个文件存储的位置由参数slave_load_tmpdir控制。文档中建议这个目录不要配置在物理机的内存目录或者重启后会删除的目录。因为复制依赖这个文件,如果意外被删除,会导致复制中断。

    5)其他

    除了上文所述的几个地方外,还有其他几个地方也会用到临时文件:

    在InnoDB层,启动的时候会创建多个临时文件用来存储:最后一次外键或者唯一键错误; 最后一次死锁的信息; 最后的innodb状态信息。用临时文件而不用内存的原因猜测是,内存使用率不会因为写这些指标而波动。

    在Server层,分区表使用show create table时,会用到临时文件。另外在MYISAM表内部排序的时候也会用到临时文件。

    三、行数据格式

    b773d1262866

    row_format.png

    MySQL的文件格式在5.7之前是只有Antelope(羚羊)一种,在5.7之后新加了一种文件格式Barracuda(梭子鱼)。

    所以MySQL的InnoDB引擎有两种文件格式:Antelope和Barracuda。

    InnoDB早期的文件格式(页格式)为Antelope,可以定义两种行记录格式,分别是Compact和Redundant

    Named File Format为了解决不同版本下页结构的兼容性,在Barracuda可以定义两种新的行记录格式Compressed和Dynamic

    变量为innodb_file_format和innodb_default_row_format

    mysql> SHOW VARIABLES LIKE 'innodb_file_format';

    +--------------------+-----------+

    | Variable_name | Value |

    +--------------------+-----------+

    | innodb_file_format | Barracuda |

    +--------------------+-----------+

    1 row in set (0.00 sec)

    mysql> SHOW VARIABLES LIKE '%row%format%';

    +---------------------------+---------+

    | Variable_name | Value |

    +---------------------------+---------+

    | innodb_default_row_format | dynamic |

    +---------------------------+---------+

    1 row in set (0.38 sec)

    复制代码

    四、参考资料

    作者:无尘老施

    链接:https://juejin.im/post/5f09a2fdf265da22ff54524e

    来源:掘金

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • MySQL 中的临时

    2021-01-28 06:55:24
    在使用 explain解析一个 sql时,有时我们会发现在 extra列上显示 using temporary ,这表示这条语句用到了临时表,那么临时表究竟是什么?它又会对 sql的性能产生什么影响?又会在哪些场景中出现?本文根据 <>...

    在使用 explain 解析一个 sql 时,有时我们会发现在 extra 列上显示 using temporary ,这表示这条语句用到了临时表,那么临时表究竟是什么?它又会对 sql 的性能产生什么影响?又会在哪些场景中出现?本文根据 <> 学习整理。

    出现场景

    其实临时表在之前的博客就已经出现过了,在 MySQL 中的排序 一文中就说到如果 order by 的列上没有索引,或者说没有用到索引,那么就需要进行额外排序(using filesort),而额外排序优先在一块 sort_buffer 空间中进行,如果这块空间大小小于要加载的字段总长度,那么就会用到临时文件辅助排序,这个临时文件就是临时表。临时表的作用就是作为中间表优化操作,比如 group by 作为分组的中间表, order by rand() (MySQL 中的排序 中的例子)作为中间表帮助运算等。

    特点

    c6d4afd3e39e308cc0c087ec3cfd27c6.png

    1、建表语法是 create temporary table …。

    2、一个临时表只能被创建它的 session 访问,对其他线程不可见,在会话结束后自动删除。所以,图中 session A 创建的临时表 t,对于 session B 就是不可见的。(所以特别适合用于join 优化)

    3、临时表可以与普通表同名。

    4、session A 内有同名的临时表和普通表的时候,show create 语句,以及增删改查语句访问的是临时表。

    5、show tables 命令不显示临时表。

    种类

    临时表分为磁盘临时表和内存临时表。磁盘临时表指的是存储在磁盘上的临时表,因为在磁盘上,所以执行效率比较低,优点结构可以是有序的,实现可以是 InnoDB(默认),MyISAM 引擎;内存临时表就是存储在内存中,执行效率高,常用的实现引擎是 Memory。

    磁盘临时表和内存临时表的区别

    1、相比于 InnoDB 表,使用内存表不需要写磁盘,往表 temp_t 的写数据的速度更快;

    2、索引 b 使用 hash 索引,查找的速度比 B-Tree 索引快;

    3、临时表数据只有 2000 行,占用的内存有限。

    Memory 引擎

    与 InnoDB 的区别

    1、InnoDB 表的数据总是有序存放的,而内存表的数据就是按照写入顺序存放的;关于这点可以通过创建 b+ 索引来进行排序,优化查询。alter table t1 add index a_btree_index using btree (id);

    2、当数据文件有空洞的时候,InnoDB 表在插入新数据的时候,为了保证数据有序性,只能在固定的位置写入新值,而内存表找到空位就可以插入新值;

    3、数据位置发生变化的时候,InnoDB 表只需要修改主键索引,而内存表需要修改所有索引;

    4、InnoDB 表用主键索引查询时需要走一次索引查找,用普通索引查询的时候,需要走两次索引查找。而内存表没有这个区别,所有索引的“地位”都是相同的。

    5、InnoDB 支持变长数据类型,不同记录的长度可能不同;内存表不支持 Blob 和 Text 字段,并且即使定义了 varchar(N),实际也当作 char(N),也就是固定长度字符串来存储,因此内存表的每行数据长度相同。

    6、内存表支持 hash 索引,并且数据存储在内存中,所以执行比数据存储在磁盘上的 Innodb 快。

    缺点

    1、锁粒度大,只支持表级锁,并发度低。

    5e1a5a1d5988fdbbb1f587bdcd4ba01e.png

    f556a7191f64cfdf9bf38dced545bc8d.png

    2、数据持久性差。因为是内存结构,所以在重启后数据会丢失 。由此会导致备库在硬件升级后数据就会丢失,并且如果主从库互为 "主备关系" ,备库在关闭后还会将删除数据记录进 binlog,重启后主机会执行备库发送过来的 binlog ,导致主库数据也会丢失。

    虽然 Memory 引擎看起来缺点很多,但是因为其存储在内存中,并且关机后会自动清除数据,所以其是作为临时表的一个绝佳选择。

    常见的应用场景

    分库分表查询

    将一个大表 ht,按照字段 f,拆分成 1024 个分表,然后分布到 32 个数据库实例上(水平分表)。一般情况下,这种分库分表系统都有一个中间层 proxy。不过,也有一些方案会让客户端直接连接数据库,也就是没有 proxy 这一层。假设分区键是 列 f 。

    1、如果只使用分区键作为查询条件如 select v from ht where f=N,那么直接通过分表规则找到 N 所在的表,然后去该表上查询就可以了。

    2、如果使用其他字段作为条件且需要排序如 select v from ht where k >= M order by t_modified desc limit 100,那么非但不能确定要查询的记录在哪张表上,而且因为默认使用的是分区键排序,所以得到的结果还是无序的,需要额外排序。

    1)在 proxy 层完成排序。优势是速度快,缺点是开发工作量比较大,如果涉及复杂的操作如 group by,甚至 join 这样的操作,对中间层的开发能力要求比较高。并且还容易出现内存不够、CPU 瓶颈的问题。

    2)将各个分区的查询结果(未排序)总结到一张临时表上进行排序。

    Ⅰ、在汇总库上创建一个临时表 temp_ht,表里包含三个字段 v、k、t_modified;

    Ⅱ、在各个分库上执行 select v,k,t_modified from ht_x where k >= M order by t_modified desc limit 100;

    Ⅲ、把分库执行的结果插入到 temp_ht 表中;

    Ⅳ、执行 select v from temp_ht order by t_modified desc limit 100;

    union 作为中间表

    有表t1: create table t1(id int primary key, a int, b int, index(a)); 有记录(1,1,1) 到 (1000,1000,1000)      执行 (select 1000 as f) union (select id from t1 order by id desc limit 2);

    解析这条 sql:

    7e956bd2d7c86eea1b4baa39654ad951.png

    可以知道:

    1、左边语句没有进行查表操作  2、右边语句使用了 id 索引  3、联合时使用了临时表

    具体过程:

    1、创建一个内存临时表,这个临时表只有一个整型字段 f,并且 f 是主键字段。

    2、执行第一个子查询,得到 1000 这个值,并存入临时表中。

    3、执行第二个子查询:

    1)拿到第一行 id=1000,试图插入临时表中。但由于 1000 这个值已经存在于临时表了,违反了唯一性约束,所以插入失败,然后继续执行;

    2)取到第二行 id=999,插入临时表成功。

    4、从临时表中按行取出数据,返回结果,并删除临时表,结果中包含两行数据分别是 1000 和 999。

    9be979ff9098fcab77d94b6e359b237f.png

    排序返回的字段过大

    举一个在  MySQL中的排序 中提到过的例子。

    select word from words order by rand() limit 3;    表数据有10000行      SQL是从10000行记录中随机获取3条记录返回。

    这个执行过程因为涉及到 rand() 且数据量比较大,所以单靠 sort_buffer 排序空间不够,所以还用到临时表。

    过程:

    1、从缓冲池依次读取记录,每次读取后都调用 rand() 函数生成一个 0-1 的数存入内存临时表,W 是 word 值,R 是 rand() 生成的随机数。到这扫描了 10000 行。

    2、初始化 sort_buffer,从内存临时表中将 rowid(这张表自动生成的) 以及 排序数据 R 存入 sort_buffer。到这因为要遍历内存临时表所以又扫描了 10000 行。

    3、在 sort_buffer 中根据 R 排好序,然后选择前三个记录的 rowid 逐条去内存临时表中查到 word 值返回。到这因为取了三个数据去内存临时表去查找所以又扫描了 3 行。总共 20003 行。

    4871ff34440e9a13341e10423f46eaab.png

    group by 作为中间表

    执行:select id%10 as m, count(*) as c from t1 group by m;

    首先解析 SQL:

    d092f4502d7be5f3652696452cbcdf03.png

    可以看到使用了临时表和额外排序,接下来来解析

    执行过程:

    1、创建内存临时表,表里有两个字段 m 和 c,主键是 m;

    2、扫描表 t1 的索引 a,依次取出叶子节点上的 id 值,计算 id%10 的结果,记为 x;

    1)如果临时表中没有主键为 x 的行,就插入一个记录 (x,1);

    2)如果表中有主键为 x 的行,就将 x 这一行的 c 值加 1;

    遍历完成后,再根据字段 m 做排序,得到结果集返回给客户端。

    a6fb1e53829de48935eddb72103903ef.png

    排序的过程就按照排序规则进行,用到 sort_buffer ,可能用到临时表。

    优化 BNL 排序

    表结构:

    CREATE TABLE`t2` (

    `id`int(11) NOT NULL,

    `a`int(11) DEFAULT NULL,

    `b`int(11) DEFAULT NULL,PRIMARY KEY(`id`),KEY`a` (`a`)

    ) ENGINE=InnoDB;

    t1、t2 结构相等,t2 100万条数据,t1 1000行数据,t1 的数据在 t2 上都有对应,相等。执行语句:select * from t1 join t2 on (t1.b=t2.b) where t2.b>=1 and t2.b<=2000;

    分析:因为字段b 没有创建索引,所以排序是属于 BNL 排序,再加上数据量比较大,所以在比较时扫描的总行数就等于  100万*1000,也就是10亿次。

    具体过程:

    1、把表 t1 的所有字段取出来,存入 join_buffer 中。这个表只有 1000 行,join_buffer_size 默认值是 256k,可以完全存入。

    2、扫描表 t2,取出每一行数据跟 join_buffer 中的数据进行对比,

    1)如果不满足 t1.b=t2.b,则跳过;

    2)如果满足 t1.b=t2.b, 再判断其他条件,也就是是否满足 t2.b 处于[1,2000]的条件,如果是,就作为结果集的一部分返回,否则跳过。

    优化:

    如果筛选字段用的比较多,那么可以为其创建索引,使 BNL 优化成 NLJ,但是如果这个字段使用的不多,那么为其创建索引反倒会因为多了不必要的维护成本而降低总体的性能。所以。针对于使用率不高的 BNL 筛选字段的优化,可以创建一个临时表,让这个临时表作为一个索引表,来优化成 NLJ,同时因为临时表在会话结束后会自动删除,省去了维护成本。

    create temporary table temp_t(id int primary key, a int, b int, index(b))engine=innodb;insert into temp_t select * from t2 where b>=1 and b<=2000;select * from t1 join temp_t on (t1.b=temp_t.b);

    这样执行过程就变成:

    1、执行 insert 语句构造 temp_t 表并插入数据的过程中,对表 t2 做了全表扫描,这里扫描行数是 100 万。

    2、之后的 join 语句,扫描表 t1,这里的扫描行数是 1000;join 比较过程中,做了 1000 次带索引的查询(因为t1 1000行,作为驱动表,t2作为被驱动表)。相比于优化前的 join 语句需要做 10 亿次条件判断来说,这个优化效果还是很明显的。

    为什么临时表可以重名

    3644bf1ed5c208e08368ca5228195342.png

    可以看到在 sessionA 在已经创建了一个名为 t1 的临时表,并且 sessionA 未结束前,sessionB 也创建了一个名为 t1 的临时表,没有发生异常。这是为什么?

    首先要知道在 MySQL 启动后每张表都会加载到内存中,所以每张表都分为内存表和磁盘表。

    1、对于磁盘表:

    1)普通表的表结构和数据文件都是存储在库名文件夹下的,文件名就是表名。

    2)结构文件存储在临时文件夹下,文件的后缀是 frm,前缀是 "#sql{进程 id}_{线程id}_序列号";

    数据文件在 5.6 及之前是存储在临时文件夹下的,5.7 开始存放在专门存放临时文件数据的临时表空间。

    2、对于内存表:

    1)普通表的命名是 "库名 + 表名"。

    2)临时表的命名则在 " 库名 + 表名 " 的基础上,加入了 " server_id + thread_id "。比如:

    1454a40874cc0eb26ac2d391429e7e0d.png

    session A 的临时表 t1,在备库的 table_def_key 就是:库名 +t1+“M 的 serverid”+“session A 的 thread_id”;

    session B 的临时表 t1,在备库的 table_def_key 就是 :库名 +t1+“M 的 serverid”+“session B 的 thread_id”。

    综上所述,因为临时表在磁盘和内存中表的命名都取自具体的进程id、线程id、所以可以实现不同的会话创建相同的表名。

    如果 binlog 的格式是 row,那么是不会记录临时表的各个操作的,因为临时表就是用于辅助各自操作的,所以在 row 格式下直接记录的是经过临时表得出的具体要操作的数据。

    总结

    临时表是一种非常方便的结构么,因为其会随着会话结束而自动删除,所以在一些查询效率较低但筛选字段使用很少的场景,就可以通过创建临时表,然后在临时表上创建索引来提高查询效率,同时也避免了索引的后续维护,而在其他复杂操作中,临时表也可以充当中间表的作用。所以临时表广泛出现在查询(多表联查)、分组、排序(排序返回的字段总长度过大)等场景中。

    总结:

    1、如果语句执行过程可以一边读数据,一边直接得到结果,是不需要额外内存的,否则就需要额外的内存,来保存中间结果;

    2、join_buffer 是无序数组,sort_buffer 是有序数组,内存临时表是二维表结构,无序;磁盘临时表默认是B+结构,可以是数组,有序。

    3、如果执行逻辑需要用到二维表特性,就会优先考虑使用临时表。比如我们的例子中,union 需要用到唯一索引约束, group by 还需要用到另外一个字段来存累积计数。

    展开全文
  • MySQL数据库中使用临时表优化查询速度2014-07-13 16:27来源:中国存储网导读:使用MySQL临时表,有时是可以加速查询的,下面就为您详细介绍使用MySQL临时表加速查询的方法,希望对您有所帮助。把表的一个子集进行...
  • 一、背景最近在使用MySQL5.6和5.7的过程中,碰到了两个问题。问题一由于一个大操作导致磁盘临时表暴涨,磁盘打满报错。...二、MySQL的临时表和临时文件2.1 临时表分类MySQL的临时表分为两种,一种是用户创建的临时...
  • SQL中的临时

    2021-08-25 01:03:43
    点击关注上方“SQL数据库开发”,设为“置顶或星标”,第一时间送达干货SQL专栏SQL基础知识第二版SQL高级知识第二版临时表定义临时表与实体表类似,只是在使用过程中,临时表是存储在系统数...
  • mysql临时表空间清理

    2021-01-18 20:48:08
    解决2.1 Binlog 文件2.2 数据文件2.3 临时文件2.4 系统文件RDS for MySQL 实例日常使用中随着实例的使用,会出现空间使用告警甚至超过实例限额被锁定的情况。比如:1. ...文章田杰2016-12-134584浏览量RDS for ...
  • 本发明涉及智能门禁卡领域,更具体地说,涉及一种可导航用临时门禁卡及其使用方法。背景技术:门禁卡是用于门禁系统中的卡,如出入证、门禁卡、停车卡、会员卡等;门禁卡在发放最终用户使用前,经由系统管理员设置,...
  • 综上三种方案,(1)由于潜在的结果集过大的问题以及灵活问题,被开发否了,目前采用的是方案(3),因为其对开发的改造较小,仅需要拆分IN语句,如果检索效率较高,测试结论符合非功能要求,就采用这种方式,若不...
  • 2019-04-07 21:46:58不可以删除哦全部2019-04-07 21:46:582019-03-28 13:14:53您好...全部2019-03-28 13:14:532019-03-21 13:43:42临时文件夹里的内容都可以直接删除。文件目录临时文件夹:C:\Documents and Setting...
  • 处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by ...
  • 如何将临时容器与持久存储结合起来是一个复杂的问题,业界已经提出、测试和改进了各种解决方案。 一个原因是持久数据存储的要求因应用程序而异。有些存储是为了长期使用,这意味着它可以慢一些。例如,在存取时间...
  • 摘要:临时表作为一个SQL标准中的表类型,各个厂商在实现时,往往却不相同,甚至行为上也存在差异,本文小结下GaussDB(DWS)的临时表使用场景。
  • MySQL数据库MySQL · 引擎特性 · 临时表那些事儿 前言相比于普通的用户数据表,MySQL/InnoDB中的临时表,大家应该会陌生很多。再加上不同的临时表创建的时机和创建的位置都不固定,这也进一步加大神秘感。最让人...
  • 从图中可以看到,nacos似乎比eureka多了一致协议,eureka是p2p,也就是非强一致,貌似nacos解决了这个问题,nacos还有控制台,嗯这个确实更方便了 一、服务注册 1.1 客户端 eureka是利用SmartLifeCycle接口的...
  • 方法一:在servlet的init()方法中缓存数据当应用...通过在init()方法中缓存一些静态的数据或完成一些只需要执行一次的、耗时的操作,就可大大地提高系统性能。例如,通过在init()方法中建立一个JDBC连接池是一个最佳...
  • 视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。相比多表查询,它使得我们获取数据更容易和快捷。 1.2 ...
  • 成员方法

    千次阅读 2021-03-10 09:42:56
    4.4成员方法成员方法描述对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块。它与过去所说的子程序、函数等概念相当。一个类或对象可以有多个成员方法,对象通过执行它的成员方法对传来的...
  • SQL SERVER数据库的临时表,是在实际需要时创建的。具体的来说,可以利用SELECT语句与CREAT语句创建临时表。如可以利用SELECT *INTO #USER_TEMP FROMUSER;通过这条语句就可以在需要的时间创建一张临时表。除此之外,...
  • 在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候去使用临时表而不使用表变量,有时候去使用表变量而不使用临时表呢?临时临时表与永久表...
  • 有多种方法可以确定 IT 系统的安全,目的是通过适当的措施提高安全。所谓的临时安全测试被广泛用于评估。这意味着研究程序的源代码及其文档,然后根据这些知识专门搜索弱点。黑客马拉松是一个奇怪的特性。这些...
  • java编程中的成员方法是什么?

    千次阅读 2021-02-12 13:09:20
    DIEA成员方法描述对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块。它与过去所说的子程序、函数等概念相当。一个类或对象可以有多个成员方法,对象通过执行它的成员方法对传来的消息作出...
  • 业务高峰期,生产环境的MySQL压力太大,没法正常响应,需要短期内临时性提升一些性能 接下来看看这些临时方案,并着重说说可能存在的风险 一、短连接风暴 正常的短连接模式就是连接到数据库后,执行很少的SQL语句...
  • 近些年,随着对于客户体验、管理水平、业务发展要求的提升,业务越来越复杂,迭代周期越来越快,如何做好提高功能测试质量?是很多技术负责人或者测试人员面对的问题。 下面针对自己经验,分享一下功能测试精髓。 ...
  • 之前说过,要想花最少的钱升级硬件,换块固态硬盘是最具价比的方案,立竿见影。 总之现在固态硬盘应该是一种趋势,你看最近新出的笔记本电脑使用的基本都是固态硬盘,传统的机械硬盘一般只有在老电脑和台式电脑...
  • 处理百万级以上的数据提高查询速度的方法:1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by ...
  • 在微服务中消息队列不仅用来消峰,还可以通过消息队列来解决微服务之间的多耦合,把同步调用转化为异步调用,减少调用链路,提升系统稳定。单体应用拆分为独立的多个无形中增加了系统的响应时间,可以通过本地缓存...
  • 一、背景最近在使用MySQL5.7的过程中,碰到了一个问题,问题是...二、MySQL的临时表和临时文件2.1 临时表分类MySQL的临时表分为两种,一种是用户创建的临时表,另一种是由优化器创建的内部临时表;临时表同时又可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 233,150
精华内容 93,260
关键字:

临时提高性功能的方法