MySQL count知多少
统计一个表的数据量是经常遇到的需求,但是不同的表设计及不同的写法,统计性能差别会有较大的差异,下面就简单通过实验进行测试(大家测试的时候注意缓存的情况,否则影响测试结果)。
1、 准备工作
为了后续测试工作的进行,先准备几张用于测试的表及数据,为了使测试数据具有参考意义,建议测试表的数据量大一点,以免查询时间太小,因此,可以继续使用之前常用的连续数生成大法,如下:
/* 创建连续数表 */
CREATE TABLE nums(id INT primary key); /* 生成连续数的存储过程,优化过后的 */
DELIMITER $$
CREATE PROCEDURE `sp_createNum`(cnt INT )
BEGIN
DECLARE i INT DEFAULT 1;
TRUNCATE TABLE nums;
INSERT INTO nums SELECT i;
WHILE i < cnt DO
BEGIN
INSERT INTO nums SELECT id + i FROM nums WHERE id + i<=cnt;
SET i = i*2;
END;
END WHILE;
END$$ DELIMITER ;
生成数据,本次准备生成1kw条记录
/* 调用存储过程 */
mysql> call sp_createNum(10000000);
Query OK, 1611392 rows affected (32.07 sec)
如果逐条循环,那时间相当长,大家可以自行测试,参考链接 效率提升16800倍的连续整数生成方法
1.1 创建innodb表
生成3张表innodb表,如下:
nums_1表只有字符串主键字段
/* 生成只有一个字符串类型字段主键的表nums_1 */
mysql> create table nums_1 (p1 varchar(32) primary key ) engine=innodb;
Query OK, 0 rows affected (0.01 sec) /* 导入数据,将id通过md5函数转换为字符串 */
mysql> insert into nums_1 select md5(id) from nums;
Query OK, 10000000 rows affected (1 min 12.63 sec)
Records: 10000000 Duplicates: 0 Warnings: 0
nums_2表有5个字段 ,其中主键为字符串类型字段的p1,其他字段为整型的id,非空的c1,可为空的c2,可为空的c3。
其中c1,c2字段内容完全一致,差别是字段约束不一样(c1不可为空,c2可为空),c3与c1,c2的差别在于c1中aa开头的值在c3中为null,其他内容一样。
/* 创建表nums_2 */
mysql> create table nums_2(p1 varchar(32) primary key ,id int ,c1 varchar(10) not null, c2 varchar(10),c3 varchar(10)) engine=innodb;
Query OK, 0 rows affected (1.03 sec) /*导入数据 */
mysql> insert into nums_2(id,p1,c1,c2,c3) select id,md5(id),left(md5(id),10),left(md5(id),10),if(,left(md5(id),10) like 'aa%',null,,left(md5(id),10)) from nums;
Query OK, 10000000 rows affected (5 min 6.68 sec)
Records: 10000000 Duplicates: 0 Warnings: 0
nums_3表的内容与nums_2完全一样,区别在于主键字段不一样,c3表为整型的id
/* 创建表nums_3 */
mysql> create table nums_3(p1 varchar(32) ,id int primary key ,c1 varchar(10) not null, c2 varchar(10),c3 varchar(10)) engine=innodb;
Query OK, 0 rows affected (0.01 sec) /* 因为内容完全一致,直接从nums_2 中导入 */
mysql> insert into nums_3 select * from nums_2;
Query OK, 10000000 rows affected (3 min 18.81 sec)
Records: 10000000 Duplicates: 0 Warnings: 0
1.2 创建MyISAM引擎表
再创建一张MyISAM的表,表结构及内容均与nums_2也一致,只是引擎为MyISAM。
/* 创建MyISAM引擎的nums_4表*/
mysql> create table nums_4(p1 varchar(32) not null primary key ,id int ,c1 varchar(10) not null, c2 varchar(10),c3 varchar(10)) engine=MyISAM;
Query OK, 0 rows affected (0.00 sec) /* 直接从nums_2表导入数据 */
mysql> insert into nums_4 select * from nums_2;
Query OK, 10000000 rows affected (3 min 16.78 sec)
Records: 10000000 Duplicates: 0 Warnings: 0
2、 查询一张表数据量的方法
查询一张表的数据量有如下几种:
查询大致数据量,可以查统计信息,2.1中会介绍具体方法
精确查找数据量,则可以通过count(主键字段),count(*), count(1) [这里的1可以替换为任意常量]
2.1 非精确查询
如果只是查一张表大致有多少数据,尤其是很大的表 只是查询其表属于什么量级的(百万、千万还是上亿条),可以直接查询统计信息,查询方式有如下几种:
查询索引信息,其中Cardinality 为大致数据量(查看主键PRIMARY行的值,如果为多列的复合主键,则查看最后一列的Cardinality 值)
mysql> show index from nums_2;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| nums_2 | 0 | PRIMARY | 1 | p1 | A | 9936693 | NULL | NULL | | BTREE | | |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
查看表状态,其中Rows为大致数据量
mysql> show table status like 'nums_2';
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| nums_2 | InnoDB | 10 | Dynamic | 9936693 | 111 | 1105182720 | 0 | 2250178560 | 4194304 | NULL | 2020-04-04 19:31:34 | NULL | NULL | utf8_general_ci | NULL | | |
+--------+--------+---------+------------+---------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
1 row in set (0.00 sec)
直接查看STATISTICS或TABLES表,内容与查看索引信息或表状态类似,其中TABLE_ROWS的内容为大致的数据量
mysql> select * from information_schema.tables where table_schema='testdb' and table_name like 'nums_2';
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+
| def | testdb | nums_2 | BASE TABLE | InnoDB | 10 | Dynamic | 9936693 | 111 | 1105182720 | 0 | 2250178560 | 4194304 | NULL | 2020-04-04 19:31:34 | NULL | NULL | utf8_general_ci | NULL | | |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------------+
1 row in set (0.00 sec)
注意:
- innodb引起的表通过以上3种方式均可查询对应表的大致数据量,且结果相同,因为均是取自相同的统计信息
- MyISAM表的结果是精确值(表数据量,不包含其他字段)
mysql> select * from information_schema.tables where table_schema='testdb' and table_name like 'nums_4';
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-----------------+----------+----------------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-----------------+----------+----------------+---------------+
| def | testdb | nums_4 | BASE TABLE | MyISAM | 10 | Dynamic | 10000000 | 75 | 759686336 | 281474976710655 | 854995968 | 0 | NULL | 2020-04-04 19:20:23 | 2020-04-04 19:21:45 | 2020-04-04 19:23:45 | utf8_general_ci | NULL | | |
+---------------+--------------+------------+------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-----------------+----------+----------------+---------------+
1 row in set (0.00 sec)
2.2 精确查找
因为2.1中innodb的表查询的结果都是统计值,非准备值,实际工作中大多数情况下需要统计精确值,那么查询精确值的方法有如下几种,且所有引擎的表都适用。
count(主键)
mysql> select count(p1) from nums_2;
+-----------+
| count(p1) |
+-----------+
| 10000000 |
+-----------+
1 row in set (1.60 sec)
count(1)
其中的1可以是任意常量,例如 count(2),count('a‘)等
mysql> select count(1) from nums_2;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (1.45 sec)
count(*)
mysql> select count(*) from nums_2;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (1.52 sec)
3、 count的性能对比
对比 count(主键) count(1) count(*) count(非空字段) count(可为空字段) 性能对比
3.1 MyISAM引擎表
3.1.1 查询整张表数据量
如果想精确查询一张MyISAM表的数据量,使用 count(主键) count(1) count(*) 效率均一致,直接查出准确结果,耗时几乎为0s
mysql> select count(p1) from nums_4;
+-----------+
| count(p1) |
+-----------+
| 10000000 |
+-----------+
1 row in set (0.00 sec) mysql> select count(1) from nums_4;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (0.00 sec) mysql> select count(*) from nums_4;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (0.00 sec)
执行计划也均一致,可以看出没有通过主键或其他索引扫描的方式统计
mysql> explain select count(*) from nums_4;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
1 row in set, 1 warning (0.00 sec) mysql> explain select count(p1) from nums_4;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
1 row in set, 1 warning (0.00 sec) mysql> explain select count(1) from nums_4;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
1 row in set, 1 warning (0.00 sec)
小结:
MyISAM的方法查整表数据量效率情况为 count(主键)= count(1) = count(*)
3.1.2 查询部分数据
查询部分数据的时候则无法直接从统计信息获取,因此耗时情况大致如下:
mysql> select count(p1) from nums_4 where p1 like 'aa%';
+-----------+
| count(p1) |
+-----------+
| 39208 |
+-----------+
1 row in set (0.14 sec) mysql> select count(1) from nums_4 where p1 like 'aa%';
+----------+
| count(1) |
+----------+
| 39208 |
+----------+
1 row in set (0.13 sec) mysql> select count(*) from nums_4 where p1 like 'aa%';
+----------+
| count(*) |
+----------+
| 39208 |
+----------+
1 row in set (0.13 sec)
执行计划其实均一样:
mysql> explain select count(1) from nums_4 where p1 like 'aa%';
+----+-------------+--------+------------+-------+---------------+---------+---------+------+-------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+-------+----------+--------------------------+
| 1 | SIMPLE | nums_4 | NULL | range | PRIMARY | PRIMARY | 98 | NULL | 42603 | 100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+-------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
小结: MyISAM引擎表统计部分数据的时候直接得出数据量,也许扫描数据进行统计,几种写法效率相近。
3.2 innodb引擎表
innodb引擎因为要支持MVCC,因此不能整表数据量持久化保存,每次查询均需遍历统计,但是不同的写法,查询效率是有差别的,后面将进行不同维度进行对比。
3.2.1 不同写法的性能对比
通过 count(主键),count(1) , count(*) 对比查询效率
mysql> select count(p1) from nums_2 ;
+-----------+
| count(p1) |
+-----------+
| 10000000 |
+-----------+
1 row in set (1.68 sec) mysql> select count(1) from nums_2 ;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (1.37 sec) mysql> select count(*) from nums_2 ;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (1.38 sec)
简单的对比发现,查询性能结果为 count(主键) < count(1) ≈ count(*)
但是查看执行计划都是如下情况
mysql> explain select count(p1) from nums_2;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | nums_2 | NULL | index | NULL | PRIMARY | 98 | NULL | 9936693 | 100.00 | Using index |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec
但是查询效率不一样,原因在于统计的方式不一样,如下:
- count(主键):innodb引擎根据对应的索引遍历整张表,把每一行的主键值都取出来,返回给 server 层。server 层拿到主键字段后,判断是不为空的(此处其实可以优化),就按行累加。
- count(1):也是遍历整张表,因为每行的结果都是1(非空),所以可以直接计数,无需判断是否为空。
- count(*): innodb引擎做了优化处理的,此种方式和count(1)类似,直接按行累计统计
3.2.2 主键字段类型不同性能对比
nums_2与nums_3内容相同,区别在于num_3的主键字段是整型的id字段,现在对比主键字段不同时查询性能的差别,
mysql> select /* SQL_NO_CACHE */count(1) from nums_2;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (2.02 sec) mysql> select /* SQL_NO_CACHE */count(1) from nums_3;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (1.69 sec)
测试发现,相同内容数据的表表主键不同,性能存在差异,且,查询时主键(索引)字段类型小的时候查询效率更好。
注:如果nums_2的id字段上添加索引后,会发现查询会走id的索引,原因在于主键索引(聚集索引)的类型是varchar(32),而id是int,索引的大小不一样,走整型的索引IO开销会少。
因此,建议MySQL的主键使用自增id作为主键(优势不仅在数据统计上,有机会在讲解)。
3.2.3 表大小不同的对比
准备工作中的nums_1 与nums_3差别在于主键都是整型的id 但是nums_3的字段更多,也就是说表更大,查询效率对比如下:
mysql> select /* SQL_NO_CACHE */count(1) from nums_1;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (1.61 sec) mysql> select /* SQL_NO_CACHE */count(1) from nums_3;
+----------+
| count(1) |
+----------+
| 10000000 |
+----------+
1 row in set (1.67 sec)
查询时间仅供参考,取决于机器性能。
由此可见表大小不同,查询效率也不同,表越小查询效率越高。
3.2.4 count(普通字段)
因为nums_3表的c2字段允许为空,但是内容均不为空,c3字段允许为空,但是存在内容为空的情况。现在将nums_3表的c2,c3字段分别统计,查看结果(先添加索引,提高查询性能)
mysql> select count(c2) from nums_3 ;
+-----------+
| count(c2) |
+-----------+
| 10000000 |
+-----------+
1 row in set (1.69 sec) mysql> select count(c3) from nums_3 ;
+-----------+
| count(c3) |
+-----------+
| 9960792 |
+-----------+
1 row in set (1.73 sec)
因为c3字段有存在null的值,索引 统计c3行数的时候会忽略null值的行。
4、 总结
以上通过对比MyISAM引擎及InnoDB引擎表通过不同写法的统计效率进行对比,可以得到如下结论:
- MyISAM表统计整表行数可以直接取出,效率最高,但是MyISAM表不支持事务
- InnoDB表统计效率 count(主键) < count(1) ≈ count(*)
- MySQL建议设置自增字段类型的主键
- 表大小越小,查询统计效率越高
其实通过准备工作中的的几张表还可以做更多的测试,感兴趣的同学可以自行测试(啰嗦一句,注意缓存,哈哈),也可关注微信公众号【数据库干货铺】进入技术交流群及时沟通,谢谢。
MySQL count知多少的更多相关文章
- 《MySQL 必知必会》读书总结
这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...
- 《MySQL必知必会》[01] 基本查询
<MySQL必知必会>(点击查看详情) 1.写在前面的话 这本书是一本MySQL的经典入门书籍,小小的一本,也受到众多网友推荐.之前自己学习的时候是啃的清华大学出版社的计算机系列教材< ...
- mysql必知必会
春节放假没事,找了本电子书mysql必知必会敲了下.用的工具是有道笔记的markdown文档类型. 下面是根据大纲已经敲完的章节,可复制到有道笔记的查看,更美观. # 第一章 了解SQL## 什么是S ...
- mysql 必知必会总结
以前 mysql 用的不是很多, 2 天看了一遍 mysql 必知必会又复习了一下基础. 200 页的书,很快就能看完, 大部分知识比较基础, 但还是了解了一些以前不知道的知识点.自己做一个备份,随 ...
- MySql必知必会实战练习(二)数据检索
在上篇博客MySql必知必会实战练习(一)表创建和数据添加中完成了各表的创建和数据添加,下面进行数据检索和过滤操作. 1. Select子句使用顺序 select--->DISTINCT---& ...
- MySQL必知必会(第4版)整理笔记
参考书籍: BookName:<SQL必知必会(第4版)> BookName:<Mysql必知必会(第4版)> Author: Ben Forta 说明:本书学习笔记 1.了解 ...
- 《mysql 必知必会》 速查指南
目录 增 添加一整行 插入多行 删 删除指定行 删除所有行 改 查 简单检索 结果筛选 结果排序 结果过滤 创建字段 处理函数 数据分组 其他高级用法 文章内容均出自 <MySQL 必知必会&g ...
- MySQL必知必会1-20章读书笔记
MySQL备忘 目录 目录 使用MySQL 检索数据 排序检索数据 过滤数据 数据过滤 用通配符进行过滤 用正则表达式进行搜索 创建计算字段 使用数据处理函数 数值处理函数 汇总数据 分组数据 使用子 ...
- mysql必知必会——GROUP BY和HAVING
mysql必知必会——GROUP BY和HAVING 创建表结构 create table `employ_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, ...
随机推荐
- PyQt5之俄罗斯方块
上个礼拜有个需求,对csv里的数据按条件进行拆分计算.一想到要做计算,少不了pandas.还有个要求最好是生成命令行工具或者带有界面. 于是尝试下,使用PyQt5做了个简单的UI界面给程序包个壳子,然 ...
- 7-11 jmu-python-分段函数&数学函数 (15 分)
本题要求计算下列分段函数f(x)的值(x为从键盘输入的一个任意实数): 输入格式: 直接输入一个实数x 输出格式: 在一行中按“f(x)=result”的格式输出,其中x与result都保留三位小数. ...
- Dubbo进阶
注册中心zookeeper 什么是注册中心: 注册中心就是用来存储服务信息的地方,就像房屋中介一样; 为什么需要注册中心: 在前面的例子中我们使用了客户端与服务器直连的方式完成了服务的调用,在实际开发 ...
- proteus pro 8.9 安装及汉化教程
最近由于网上上课老师要求我们自己安装proteus这款仿真软件,所以笔者也安装了最新款版的proteus pro 8.9,分享给大家安装心得,也包含汉化过程,希望大家能用软件好好学习. 备注:感谢博主 ...
- 致远·面向人工智能-逐浪CMS v8.1.2全面发布[全球首个基于dotNET core3.0的中文CMS]
原文:https://www.z01.com/down/3484.shtml 再远, 我都不会停息, 因为技术而生, 因为技术而强, 这是逐浪软件的命与根! 全新打造, 三百多项超级功能, 助你十分钟 ...
- MATLAB神经网络(4) 神经网络遗传算法函数极值寻优——非线性函数极值寻优
4.1 案例背景 \[y = {x_1}^2 + {x_2}^2\] 4.2 模型建立 神经网络训练拟合根据寻优函数的特点构建合适的BP神经网络,用非线性函数的输入输出数据训练BP神经网络,训练后的B ...
- Java反射之构造方法反射
上一篇Java反射之Class类我们介绍了java反射的关键类Class, 反射就是由一个java类映射得到一个java类. 所以,我们自然能想到,一个类中应该有哪些属性,这里做个比方,人有名字年龄等 ...
- OFD电子证照模版制作工具 --(采用wpf开发)
前言 ofd应用的范围非常广,电子证照是其中非常重要的一个应用.同一类电子证照具有相同的板式.元数据:所以电子证照非常适合用模版来制作.模版就是板式样式固定,每个具体的证照只是文字或图片内容不同.比 ...
- Leetcode 1160: 拼写单词
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌 ...
- 爬虫前奏——初谈Requests库
什么是Requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库如果你看过上篇文章关于urllib库的使用,你会发现,其 ...