当前位置:   article > 正文

MongoDB 优化——如何提高读写性能_mongodb读写性能

mongodb读写性能

1、批量插入与逐条插入的性能差异

实测本地MongoDB插入10万条数据,逐条插入需要40秒,批量插入仅需2.3秒。单本地批量插入数据的性能就远远超过逐条插入数据的性能。如果使用远程数据库,那么这个I/O导致的时间消耗会比这个差异许多倍。那么,我们怎么正确的批量插入数据呢?
下面推荐两个案例:

  • 使用Redis批量插入一次性数据
import redis
import json
import pymongo

client = redis.Redis()
handler = pymongo.MongoClient().数据库.集合

文档信息列表 = []
while True:
	文档信息_JSON = client.lpop('Redis中的表名')
	if 文档信息_JSON:
		文档信息 = json.loads(文档信息_JSON.decode())
		文档信息列表.append(文档信息)
		if len(文档信息列表) >= 1000:
			handler.insert_many(文档信息列表)
			文档信息列表.clear()
	else:
		break
if 文档信息列表:
	handler.insert_many(文档信息列表)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 使用Redis插入持续性数据
import redis
import json
import time
import pymongo

client = redis.Redis()
handler = pymongo.MongoClient().数据库名.集合名

文档信息列表 = []
get_count = 0
while True:
	文档信息_JSON = client.lpop('Redis中的表名')
	if 文档信息_JSON:
		文档信息 = json.loads(文档信息_JSON.decode())
		文档信息列表.append(文档信息)
		if len(文档信息列表)>=1000:
			handler.insert_many(文档信息列表)
			文档信息列表.clear()
	else:
		if 文档信息列表 and get_count%1000 == 0:
			handler.insert_many(文档信息列表)
			文档信息列表.clear()
		time.sleep(同步时间)
	get_count += 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2、插入和更新数据的性能差异

实测本地MongoDB更新10万条数据耗时60秒,插入十万条数据耗时2.5秒【包括改名,删除原集合等操作】

3、使用索引提高查询速度

索是一种特殊的数据结构,它使用了能够快速遍历的形式记录了集合中数据的位置。数据到了千万量级后,有了索引在一秒内就能查询出结果。
创建索引:

import pymongo

handler = pymongo.MongoClient().数据库名.集合名
handler.create_index("字段", background=True)
  • 1
  • 2
  • 3
  • 4

其中,对指定字段创建索引,关于background参数:

  • False:创建集合时,这个集合不能被查询,也不能被写入,但是创建速度快。
  • True:创建集合的速度会慢一些,但不影响其他程序读写这个集合

索引只需要添加一次,之后的数据MongoDB会自动处理。

4、引入Redis,降低MongoDB的读取速率【重要】

比如爬虫爬取新闻,会从各个网站爬取新闻,然后存到MongoDB中,为了不存入重复的新闻,爬虫需要根据新闻标题来判断该新闻是否已经在数据库中了,如果每一条新闻标题都去MongoDB里比对一遍,就会严重影响性能。
所以,我们可以这样:
当爬虫启动时,先读取一遍数据库中的新闻标题,然后把他全放入Redis中的Title集合中,接下来就不需要读取MongoDB了,爬虫每爬取一条新闻,就线使用sadd命令命令将他添加到Title集合中:

  • 如果返回1,表示以前没有此条新闻,再将其插入MongoDB【或者攒够1000条,批量插入】,插入成功
  • 如果返回0,表示有这条新闻了,直接丢弃

示例代码:

def init():
	all_title = mongo_handler.distinct('title')
	redis_client.sadd('Title', *all_title)

def need_insert_news(news_title):
	if redis_client.sadd('Title', news_title) == 1:
		return True
	return False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
5、增加补充信息,提高查询速度

在往数据库添加信息之前,如果能判断该条数据的某些属性符合要求的时候,可以增加一个字段,标记为True或False,查询时就能便利许多。虽然这个字段看似冗余,但会极高的提升速度。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/734355
推荐阅读
相关标签
  

闽ICP备14008679号