近日看到国务院印发的《全国不同风险地区企事业单位复工复产疫情防控措施指南》中提到了低风险,中风险和高风险地区,搜索发现只能通过“国务院客户端微信小程序”以区/县为单位进行查询,想了解一下全国各地的形式需要挨个查询,没有一个可以纵览全局的地图,心血来潮想要自己画一个。
数据源
网上常见的查询入口都是微信小程序,但是微信小程序相对封闭,咱也不属于数据获取相对不方便,想找个普通的网站服务。经过一番搜索发现国家政务服务平台也提供了一个区/县疫情风险等级查询入口,开干。
近日看到国务院印发的《全国不同风险地区企事业单位复工复产疫情防控措施指南》中提到了低风险,中风险和高风险地区,搜索发现只能通过“国务院客户端微信小程序”以区/县为单位进行查询,想了解一下全国各地的形式需要挨个查询,没有一个可以纵览全局的地图,心血来潮想要自己画一个。
网上常见的查询入口都是微信小程序,但是微信小程序相对封闭,咱也不属于数据获取相对不方便,想找个普通的网站服务。经过一番搜索发现国家政务服务平台也提供了一个区/县疫情风险等级查询入口,开干。
表结构优化、索引优化、查询优化缺一不可,需要齐头并进。
MySQL 的联表算法是基于嵌套循环算法(nested-loop algorithm)而衍生出来的一系列算法,根据不同条件而选用不同的算法
1 | // Simple Nested-Loop |
Simple Nested-Loop
最为简单粗暴,毫无性能可言,事实上不会使用这种算法。
Block Nested-Loop
缓存块嵌套循环连接,简称 BNL,是对 SNL 的一种优化。一次性缓存多条驱动表的数据到 Join Buffer,然后拿 Join Buffer 里的数据批量与内层循环读取的数据进行匹配。将内部循环中读取的每一行与缓冲区中的所有记录进行比较,这样就可以减少内层循环的读表次数。原来内层循环的读表次数是外层循环的行数 n,如今读表次数为 n/buffer_size。
Index Nested-Loop
索引嵌套循环,简称 INL,是基于被驱动表的索引进行连接的算法;驱动表的记录逐条与被驱动表的索引进行匹配,避免和被驱动表的每条记录进行比较。
Batched Key Access
是对INL的进一步优化,详见文档。
查询需要在不同的地方花费时间,包括网络,CPU 计算,生成统计信息和执行计划,锁等待等操作,尤其是底层存储引擎检索数据,这些检索需要内存操作、CPU 操作和内存不足时的 IO 操作。
分析步骤
查询不需要的记录
使用 SELECT 查询所有结果,获取前面的 N 行后关闭,实际上 MySQL 已经查询出全部结果。需要多少查多少,用 LIMIT 进行限制。
取出全部列
不要使用 SELECT * FROM a INNER JOIN b INNER JOIN C;
这样的语句。很多时候取出全部列是不必要的。并且,取出全部列会让优化器无法完成索引覆盖这类优化,还会为服务器带来额外的 IO、内存和 CPU 的消耗。
有时候出于开发效率,应用程序可以通过缓存进行复用等角度也可以查询这些多余的数据,需要进行权衡。
重复查询相同的数据
利用缓存,减少重复查询。
索引可以包含一个或多个列的值,MySQL 只能高效地使用索引的最左前缀,如果索引包含多个列,那么列的顺序也十分重要。
B 树索引
B 树中所有的值按顺序存储,每个叶节点到根的距离相同。
索引对多个值进行排序的依据是CREATE TABLE
语句中定义索引时列的顺序。
B 树适用于全键值、键值范围或键前缀查找:
索引树中的节点是有序的,因此还可以用于查询中的ORDER BY
操作。如果ORDER BY
子句满足前面列出的集中查询类型,则索引也可以满足对应的排序需求。
B 树索引的限制:
last_name, first_name, birthday
创建索引,索引无法用于查询名字为 Bill 的人,也无法用于查找某个特定的生日。类似的,无法查找姓氏以某个字结尾的人。三层架构:
每个连接拥有一个线程,线程的创建和销毁消耗资源,可以通过维护线程池的方式,提高性能。
注意区分线程池
和连接池
,连接池一般在客户端设置,而线程池是在 DB 服务器上配置。连接池可以减少连接的创建和释放,提高请求的平均响应时间,控制一个应用的 DB 连接数,但无法控制整个应用集群的连接数规模。线程池
和连接池
需要结合使用。
MySQL 的优化器不关心使用的是什么存储引擎,但存储引擎对于优化查询有影响。优化器会请求存储引擎提供容量或某个具体操作的开销信息,以及表数据的统计信息。
Oracle 中有库基于规则优化 (RBO) 和基于代价优化 (CBO) 两种方式,但oracle 10g
之后已经弃用 RBO。相比 MySQL 的优化器,Oracle 的优化更加丰富和完善,可以对照着学习。
想要寻找一个合适的算法不容易,实际应用中,我们一般采用启发式实验。
没有免费的午餐定理 (NFL):核心在于,假设了所有问题出现的机会相同,或所有问题同等重要。当需求是解决一切问题时,“哪个算法更好”就毫无意义。HG2G 中“深思”面对“宇宙、生命以及一切的中继答案是什么?”这样一个问题,用最复杂的算法算出一个 42 和随便说一个 42 是一样的。
偏差与方差窘境: