python--mongodb查询优化

最近在处理爬取之后存储在mongodb上的数据.数据量150w左右.整个流程为:提取所有存储在mongodb中的数据–数据转换–对接Java服务上redis–数据上线

最初方案:

from pymongo import MongoClient
con = MongoClinet(host,port)
collections = con[db][collection]
# find({条件查询},{需要显示的字段1为显示,0为不显示})
data = collections.find({},{"_id":0})
data_num = estimated_document_count() # 获取数据总数
for cursor in range(data_num):
	print(data[cursor])

这种常见的查询读取当数据达到上万的时候读取时间会从0.01慢慢增加到几秒.这个时候了解到了python对接mongo返回回来的是游标,使用find函数返回的是一个生成器,需要配合for循环取读取数据而我们大量的时间就消耗在了游标耗时中.

优化方案二:

在发现了这个问题的时候进行了方案第二次的优化采用了网上常见的skip,limit配合

from pymongo import MongoClient
con = MongoClinet(host,port)
collections = con[db][collection]
data_num = estimated_document_count()
# find({条件查询},{需要显示的字段1为显示,0为不显示})
for num in range(0,data_num,1000):
# skip表示限制前面的数据,limit表示显示多少数据,两者结合表示为翻页 
	result = collections.find({},{"_id":0}).skip(num).limit(1000)
	# 此为读取整页数据
	for number in range(1000):
		print(result[number])

此方案适合数据量在5万一下的小数据进行操作,当数据量超过5万查询查询可能会达到几十秒慢搜索

优化方案三:

当达到上5万以上的时候发现真的跑不动 简直心累几十秒一条数据一百多万数据怎么跑?而且2天内要上线,查了一圈的资料发现网上几乎都是skip,limit,然而问题就出现在skip上当数据达到一定量的时候skip受限影响速度翻阅了一些书恍然想起两点没有做,解决方案为2点

  1. 使用关键字作为MONGO索引,通过mongo语句设置db.user.ensureIndex({“name”:1}),可以使用db.user.find().explain()或者explain(“executionStats”)可以查看到当进行搜索的时候不再是全表搜素而且通过索引搜索,速度快上10倍以上
  2. 使用索引进行排序(或者也可以复合索引查询)
from pymongo import MongoClient
con = MongoClinet(host,port)
collections = con[db][collection]
data_num = collections.estimated_document_count()
# find({条件查询},{需要显示的字段1为显示,0为不显示})
remember = None
cursor = collections.find({},{"_id":0}).limit(100)
if remember:
#记录下索引并利用所以进行查找,查询比已记录的索引$gt为更大的数据也可以使用$lt等,sort为将索引排序
#建议索引为int,或者string类的数字,在mongo里面索引string为数字也会根据数字大小排序
	cursor = collections.find({"index":{"$gt":remember}},{"_id":0}).sort({"index":1}).limit(100)
for num in range(100):
	data = cursor[num]
	remember = data["index"]

此方案适用于大多数查询

优化方案四:

此方案为最终版,目前为止是所有流程跑完5秒左右上线100条数据,一天能将目前数据库中的所有数据全部上线.
我们一般使用的pymongo为同步,而这次方案中使用的是一个异步模块motor

import asyncio
from motor.motor_asyncio import AsyncIOMotorClient
	
MONGO = AsyncIOMotorClient(host="localhost", port="27017")
MONGO_DATA = MONGO["db"]["collection"]
async def find_data():
	cursor = collections.find({},{"_id":0}).limit(100)
	rember = None
	if remember:
		cursor = collections.find({"index":{"$gt":remember}},{"_id":0}).sort({"index":1}).limit(100)
		for data in await data.to_list(length=100):
			print(data)

motor操作不做细说,一般的操作基本上都是一样的,需要详情一些的操作命令推荐可以看看[https://www.cnblogs.com/syncnavigator/p/10193493.html]
如果需要了解关于mongo的性能调优推荐可以看看[https://blog.csdn.net/happy_jijiawei/article/details/53737858]这篇文章
如果在需要对数据库更深的了解 公司大佬是让我直接去看关于mysql相关知识书,一通百通.
看到一篇文章上面写的一句话很赞同:好的性能不是调出来的,是设计出来的.
实践基于知识,好的设计基于对对象的了解.

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,可以使用Pillow库来压缩图片,然后使用PyMongo库将压缩后的图片插入MongoDB中。下面是一个示例: 首先,需要安装Pillow和PyMongo库: ``` pip install pillow pymongo ``` 接下来,假设有一个名为 `images` 的集合,其中有一个名为 `image` 的字段用于存储图片。可以使用以下代码将压缩后的图片插入到该集合中: ```python from PIL import Image from io import BytesIO import pymongo # 连接到MongoDB client = pymongo.MongoClient("mongodb://localhost:27017/") db = client["mydatabase"] collection = db["images"] # 打开图片文件 with open("example.jpg", "rb") as f: # 读取图片数据 img_data = f.read() # 将图片数据加载到Pillow中 img = Image.open(BytesIO(img_data)) # 压缩图片 img = img.resize((int(img.width / 2), int(img.height / 2))) # 将压缩后的图片转换为字节流 output = BytesIO() img.save(output, format="JPEG") output_data = output.getvalue() # 将压缩后的图片插入到MongoDB中 result = collection.insert_one({"image": output_data}) print("Inserted image with ID:", result.inserted_id) ``` 以上代码中,首先连接到MongoDB,然后打开图片文件并读取图片数据。接下来,将图片数据加载到Pillow中,并对图片进行压缩。然后,将压缩后的图片转换为字节流,并使用PyMongo将该字节流插入到MongoDB中。 执行以上代码后,会将压缩后的图片插入到MongoDB中,并输出该图片的ID。注意,该示例仅演示了如何将压缩后的图片插入到MongoDB中,实际应用中可能需要对图片进行更多的处理和优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值