当前位置: 首页 > news >正文

做网站需要有服务器网站建设哪些公司好

做网站需要有服务器,网站建设哪些公司好,公共服务标准化指南,传奇手游网站作者总结了 MySQL 中所有触发使用内部临时表的场景。 作者#xff1a;刘嘉浩#xff0c;爱可生团队 DBA 成员#xff0c;重度竞技游戏爱好者。 爱可生开源社区出品#xff0c;原创内容未经授权不得随意使用#xff0c;转载请联系小编并注明来源。 本文约 2000 字#xff…作者总结了 MySQL 中所有触发使用内部临时表的场景。 作者刘嘉浩爱可生团队 DBA 成员重度竞技游戏爱好者。 爱可生开源社区出品原创内容未经授权不得随意使用转载请联系小编并注明来源。 本文约 2000 字预计阅读需要 5 分钟。 临时表属于是一种临时存放数据的表这类表在会话结束时会被自动清理掉但在 MySQL 中存在两种临时表一种是外部临时表另外一种是内部临时表。 外部临时表指的是用户使用 CREATE TEMPORARY TABLE 手动创建的临时表。而内部临时表用户是无法控制的并不能像外部临时表一样使用 CREATE 语句创建MySQL 的优化器会自动选择是否使用内部临时表。 那么由此引发一个问题MySQL 到底在什么时候会使用内部临时表呢 我们将针对 UNION、GROUP BY 等场景进行分析。 UNION 场景 首先准备一个测试表。 CREATE TABLE employees (id int NOT NULL AUTO_INCREMENT,first_name varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,last_name varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,sex enum(M,F) COLLATE utf8mb4_bin DEFAULT NULL,age int DEFAULT NULL,birth_date date DEFAULT NULL,hire_date date DEFAULT NULL,PRIMARY KEY (id),KEY last_name (last_name),KEY hire_date (hire_date) ) ENGINEInnoDB AUTO_INCREMENT500002 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin; 准备插入数据的脚本。 #! /usr/bin/python #! codingutf-8import random import pymysql from faker import Faker from datetime import datetime, timedelta# 创建Faker实例 fake  Faker()# MySQL连接参数 db_params  {host: localhost,user: root,password: root,db: db1,port: 3311 }# 连接数据库 connection  pymysql.connect(**db_params)# 创建一个新的Cursor实例 cursor  connection.cursor()# 生成并插入数据 for i in range(5000):id  (i1)first_name  fake.first_name()last_name  fake.last_name()sex  random.choice([M, F])age  random.randint(20, 60)birth_date  fake.date_between(start_date-60y, end_date-20y)hire_date  fake.date_between(start_date-30y, end_datetoday)query  fINSERT INTO employees (id, first_name, last_name, sex, age, birth_date, hire_date)VALUES ({id}, {first_name}, {last_name}, {sex}, {age}, {birth_date}, {hire_date});cursor.execute(query)# 每1000提交一次事务if (i1) % 1000  0:connection.commit()# 最后提交事务 connection.commit()# 关闭连接 cursor.close() connection.close() 在创建好测试数据后执行一个带有 UNION 的语句。 rootlocalhost:mysqld.sock[db1] explain (select 5000 as res from dual) union (select id from employees order by id desc limit 2); ------------------------------------------------------------------------------------------------------------------------------------------ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | ------------------------------------------------------------------------------------------------------------------------------------------ | 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | | 2 | UNION | employees | NULL | index | NULL | PRIMARY | 4 | NULL | 2 | 100.00 | Backward index scan; Using index | | NULL | UNION RESULT | union1,2 | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | ------------------------------------------------------------------------------------------------------------------------------------------ 3 rows in set, 1 warning (0.00 sec) 可见第二行中 key 值是 PRIMARY即第二个查询使用了主键 ID。第三行 extra 值是 Using temporary表明在对上面两个查询的结果集做 UNION 的时候使用了临时表。 UNION 操作是将两个结果集取并集不包含重复项。要做到这一点只需要先创建一个只有主键的内存内部临时表并将第一个子查询的值插入进这个表中这样就可以避免了重复的问题。因为值 5000 早已存在临时表中而第二个子查询的值 5000 就会因为冲突无法插入只能插入下一个值 4999。 UNION ALL 与 UNION 不同并不会使用内存临时表下列例子是使用 UNION ALL 的执行计划。 rootlocalhost:mysqld.sock[db1] explain (select 5000 as res from dual) union all (select id from employees order by id desc limit 2); ---------------------------------------------------------------------------------------------------------------------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | ---------------------------------------------------------------------------------------------------------------------------------------- | 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used | | 2 | UNION | employees | NULL | index | NULL | PRIMARY | 4 | NULL | 2 | 100.00 | Backward index scan; Using index | ---------------------------------------------------------------------------------------------------------------------------------------- 2 rows in set, 1 warning (0.01 sec)因为 UNION ALL 并不需要去重所以优化器不需要新建一个临时表做去重的动作执行的时候只需要按顺序执行两个子查询并将子查询放在一个结果集里就好了。 可以看到在实现 UNION 的语义上临时表起到的是一个暂时存储数据并做去重的动作的这么一种作用的存在。 GROUP BY 除了 UNION 之外还有一个比较常用的子句 GROUP BY 也会使用到内部临时表。下列例子展示了一个使用 ID 列求余并进行分组统计且按照余数大小排列。 rootlocalhost:mysqld.sock[db1] explain select id%5 as complementation,count(*) from employees group by complementation order by 1; -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 1 | SIMPLE | employees | NULL | index | PRIMARY,last_name,hire_date | hire_date | 4 | NULL | 5000 | 100.00 | Using index; Using temporary; Using filesort | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 row in set, 1 warning (0.00 sec)可以看到 extra 的值是 using index、using temporary、using filesort; 这三个值分别是使用索引、使用临时表、使用了排序。 注意在 MySQL 5.7 版本中 GROUP BY 会默认按照分组字段进行排序在 MySQL 8.0 版本中取消了默认排序功能所以此处使用了 ORDER BY 进行复现。 对于 GROUP BY 来说上述的语句执行后会先创建一个内存内部临时表存储 complementation 与 count(*) 的值主键为 complementation。然后按照索引 hire_date 对应的 ID 值依次计算 id%5 的值记为 x如果临时表中没有主键为 x 的值那么将会在临时表中插入记录如果存在则累加这一行的计数 count(*)。在遍历完成上述的操作后再按照 ORDER BY 的规则对 complementation 进行排序。 在使用 GROUP BY 进行分组或使用 DISTINCT 进行去重时MySQL 都给我们提供了使用 hint 去避免使用内存内部临时表的方法。 hint解释SQL_BIG_RESULT显式指定该 SQL 语句使用磁盘内部临时表适合大数据量的操作适用于 InnoDB 引擎与 Memory 引擎。SQL_SMALL_RESULT显式指定该 SQL 语句使用内存内部临时表速度更快适合小数据量的操作适用于 Memory 引擎。 下列是一个使用了 SQL_BIG_RESULT 的例子。 rootlocalhost:mysqld.sock[db1] explain select SQL_BIG_RESULT id%5 as complementation,count(*) from employees group by complementation order by 1; --------------------------------------------------------------------------------------------------------------------------------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | --------------------------------------------------------------------------------------------------------------------------------------------------- | 1 | SIMPLE | employees | NULL | index | PRIMARY,last_name,hire_date | hire_date | 4 | NULL | 5000 | 100.00 | Using index; Using filesort | --------------------------------------------------------------------------------------------------------------------------------------------------- 1 row in set, 1 warning (0.00 sec) 从执行计划中我们可以看出使用了 SQL_BIG_RESULT 这个 hint 进行查询后在 extra 列中 Using Temporary 字样已经不见了即避免了使用内存内部临时表。 其他场景 当然除了上述两个例子外MySQL 还会在下列情况下创建内部临时表 对于UNION语句的评估但有一些后续描述中的例外情况。对于某些视图的评估例如使用 TEMPTABLE 算法、UNION 或聚合的视图。对派生表的评估。对公共表达式的评估。用于子查询或半连接材料化的表。对包含 ORDER BY 子句和不同 GROUP BY 子句的语句的评估或者对于其中 ORDER BY 或 GROUP BY 子句包含来自连接队列中第一个表以外的表的列的语句。对于 DISTINCT 与 ORDER BY 的组合可能需要一个临时表。对于使用 SQL_SMALL_RESULT 修饰符的查询MySQL 使用内存中的临时表除非查询还包含需要在磁盘上存储的元素。为了评估从同一表中选取并插入的 INSERT … SELECT 语句MySQL 创建一个内部临时表来保存 SELECT 的行然后将这些行插入目标表中。对于多表 UPDATE 语句的评估。对于 GROUP_CONCAT() 或 COUNT(DISTINCT) 表达式的评估。窗口函数的评估根据需要使用临时表。 值得注意的是某些查询条件 MySQL 不允许使用内存内部临时表在这种情况下服务器会使用磁盘内部临时表。 表中存在 BLOB 或 TEXT 列。MySQL 8.0 中用于内存内部临时表的默认存储引擎 TempTable 从 8.0.13 开始支持二进制大对象类型。如果使用了 UNION 或 UNION ALLSELECT 的列表中存在任何最大长度超过 512 的字符串列对于二进制字符串为字节对于非二进制字符串为字符。SHOW COLUMNS 和 DESCRIBE 语句使用 BLOB 作为某些列的类型因此用于此结果的临时表是将会是磁盘内部临时表。 参考资料 [1]: 丁奇 《MySQL45讲》 37.什么时候会使用内部临时表 [2]: 8.4.4 Internal Temporary Table Use in MySQL URL:https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html 更多技术文章请访问https://opensource.actionsky.com/ 关于 SQLE SQLE 是一款全方位的 SQL 质量管理平台覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库为开发和运维提供流程自动化能力提升上线效率提高数据质量。 SQLE 获取 类型地址版本库https://github.com/actiontech/sqle文档https://actiontech.github.io/sqle-docs/发布信息https://github.com/actiontech/sqle/releases数据审核插件开发文档https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
http://www.zqtcl.cn/news/915287/

相关文章:

  • 国内设计网站公司wordpress电视主题下载
  • 自贡网站开发河南省建设网站首页
  • 昆明网站推广优化服务器代理
  • wordpress 网站统计插件福建省建设工程职业注册网站
  • 手机移动端网站是什么上海网站设计服务商
  • 多语言网站建设推广孝感门户网
  • 外贸soho 网站建设旅游电子商务网站建设调查问卷
  • 北京专业制作网站seo优化技术教程
  • 网站建设最低多少钱珠海在线网站制作公司
  • 网站建设完成之后要索取哪些医疗网站建设服务
  • 长沙招聘网站有哪些深圳seo论坛
  • 网站如何做网络推广山西住房建设厅官方网站
  • 优化排名推广技术网站平面设计创意
  • 山西网站建设哪家有tv域名的网站
  • 个人博客网站怎么赚钱公司招聘一个网站建设来做推广
  • 功能型网站有哪些中国门户网站有哪些
  • 网站制作教程步骤软件公司怎么赚钱
  • 看世界杯网址网站更新seo
  • 深圳网站做的好的公司商洛做网站电话
  • 环保部网站官网建设项目审批做网站推广赚钱吗
  • 北仑建设局网站东莞市seo网络推广价格
  • 大专学历怎么自考优化建站
  • 网站上的图片怎么替换中国电力建设集团网站
  • 开发手机网站步骤手机网站前端开发布局技巧
  • 文山文山市网站建设网站建设管理教程视频
  • 深圳建筑业协会官网seo短视频新地址在哪里
  • 学院宣传网站制作大型网站团队人数
  • 新品发布会ppt参考友山建站优化
  • 做网站云服务器装系统厦门网站建设哪家强
  • 网站建设顶呱呱东莞建设信息网官网