关灯
护眼 字体:大
中
小
上一章
章节列表
下一页
无论SQL数据库还是NoSQL数据库,都有一些通用的技巧可以大大提高读写性能。作为NoSQL的MongoDB有自己的一些特性。将这些特性应用到生产环境中时,需要提高警惕,以防导致不必要的麻烦。
MongoDB默认没有密码,且只允许本地访问。如果开放外网访问,就一定要设置密码,否则会有安全隐患。
8.1 提高MongoDB读写性能
使用一些简单的技巧,就可以大大提高 MongoDB 的读写性能。本节将介绍其中几种常见的技巧。
8.1.1 实例26:“批量插入”与“逐条插入”数据,比较性能差异
实例描述
在 MongoDB 中,分别用“逐条插入”与“批量插入”两种方式插入相同的数据,比较两者的时间差。
使用Python向MongoDB中插入一条数据,只需要3行代码,见代码8-1。
代码8-1 插入一条数据到MongoDB
从Python执行完成第3行代码,到数据存到数据库中,这个过程可能只需要几毫秒。但是在这几毫秒中,网络传输的时间占了非常大的比例。
I/O(Input/Ouput,输入/输出)操作总是最耗费时间的,无论是硬盘的I/O操作还是网络I/O操作。
● 如果写到本地的MongoDB,数据会在网卡中转一圈再存入硬盘。
● 如果写到远程的MongoDB,数据会先从本地网卡出去,然后经过网线,在电磁波、光信号、电信号之间进行转换,中间通过一层一层的交换机路由器,甚至海底光缆,绕地球一圈再进入目标服务器的网卡最后存入数据库。
这就像是扔砖头,分10次,每次只扔一块砖头的时间,肯定远远大于把10块砖一次扔出去的时间。如果你能够一次扔10块砖头,为什么你要一块一块地扔呢。
现在的宽带技术,上下行速度动辄每秒几百兆字节。如果使用 MongoDB 插入数据还在逐条插入,每一条几个字节,那可真是白白浪费了网络带宽。
下面通过实际数据来对比逐条插入数据和批量插入数据的性能差异。
1.生成初始数据
为了对比结果的公平性,首先生成一个CSV文件,这个文件中的数据将用于测试逐条插入与批量插入功能。
运行generate_people_info.py,会在当前文件夹下面生成一个people_info.csv文件,如图8-1所示。
图8-1 生成初始数据
people_info.csv一共有119 810行,除去第1行标题行和最后1行空白行,一共有119 808条数据将会被插入MongoDB中。
提示:
由于“age”“salary”“phone”这3个字段使用了随机数,所以每一次重新生成的数据都不同。读者自行生成的people_info.csv应该和图中有所差异,这是正常情况。读者只需要保证逐条插入和批量插入使用的数据相同即可。
2.逐行插入数据
编写一段Python代码,读取CSV文件并逐条插入到MongoDB中。代码如下:
代码8-2 计算逐条插入数据的时间
其中,主要代码说明如下。
● 第5~7行代码:使用Python自带的CSV模块读取CSV文件,并将其转换为包含字典的列表。其中每一个字典为CSV中的一行数据。
● 第9行代码:初始化MongoDB并连接到chatper_8库下面的one_by_one集合。
● 第11行代码:记录开始时间戳。
● 第12、13行代码:使用for循环把数据逐条插入到MongoDB中。
● 第14、15行代码:记录结束时间戳,并打印出时间差。
运行效果如图8-2所示。插入119 808条数据,共耗时44秒。
图8-2 逐条插入119808条数据,耗时44秒
3.批量插入数据
编写一段Python代码,测试批量插入数据的性能,见代码8-3。
代码8-3 计算批量插入数据的时间
其中,主要代码说明如下。
● 第5~7行代码:使用Python自带的CSV模块读取CSV文件,并将其转换为包含字典的列表。其中每一个字典为CSV中的一行数据。
● 第9行代码:初始化MongoDB,并连接到chatper_8库下面的batch集合。
● 第11行代码:记录开始时间戳。
● 第12行代码:使用insert_many()方法直接把包含字典的列表插入数据库。
● 第13、14行代码:记录结束时间戳,并打印时间差。
运行效果如图8-3所示。批量插入119 808条数据,只用了不到2.7秒。
图8-3 批量插入119808条数据,耗时2.7秒
4.如何正确批量插入数据
仅仅是使用本地的MongoDB数据库,批量插入数据的性能就远远超过逐条插入数据性能。如果使用的是远程数据库,那么网络I/O导致的时间消耗会比这个差异大很多倍。
既然批量插入数据库的性能这么好,那如何正确地使用批量插入功能?下面这一段代码想实现的功能是:从Redis里面读数据,再插入到MongoDB中。请读者看看这段代码有什么问题。
代码8-4 一段有多种崩溃可能的批量插入数据的示例代码
其中,主要代码说明如下。
● 第6行代码:初始化Redis连接。
● 第7行代码:初始化MongoDB连接。
● 第10行代码:开启一个永远运行的循环。
● 第11行代码:在Redis中名为people_info的列表左侧获取一条数据,并将数据赋值给people_info_json变量。
● 第12~14行代码:如果people_info_json不为空,则使用JSON模块把它转换为字典,然后将其添加到people_info_list列表中。
m.qiduwx.com提示您,本章没有阅读完,点击下一页进入下一页阅读!
上一章
章节列表
下一页