实战中提升 MongoDB 性能的一些小技巧

2023年 10月 12日 73.0k 0

MongoDB 是一种流行的面向文档的 NoSQL 数据库,以其灵活性、可扩展性和高性能而著称。但是,要使 MongoDB 达到最佳性能,您需要遵循一些关键的优化策略。本文将探讨一些优化 MongoDB 的技巧。

适当索引

索引允许 MongoDB 仅通过快速搜索索引字段来高效执行查询。如果没有索引,MongoDB 将不得不扫描集合中的每个文档,以选择匹配的文档。

适当的索引对于快速查询性能至关重要。您应该在经常查询的字段上创建索引。

// Create index on `name` field 
db.products.createIndex({name: 1})

// Create compound index on `name` and `price`
db.products.createIndex({name: 1, price: -1})

使用覆盖查询

覆盖查询是指索引包含查询所扫描的所有字段的查询。这样,MongoDB 就能从索引中获取所有查询数据,而无需查找documents。

// Covered query
db.products.find(
    {price: {$gt: 30}}, 
    {name: 1, price: 1} // fields 
)

这里的索引包含名称和价格字段,因此不需要全文查找。

嵌入相关数据

MongoDB 采用灵活的模式设计,允许在文档中嵌入相关数据。嵌入相关数据可减少查询和连接次数。

// Embed 'comments' array in product document
{
   name: "Product 1",
   price: 100,
   comments: [
      {user: "user1", text: "Nice!"},
      {user: "user2", text: "Lovely"}
   ]
}

现在,检索评论只需对产品集合进行一次查询即可,无需连接。

使用分片进行水平扩展

分片将数据分布在多个服务器上,这些服务器被称为分片。这提供了横向可扩展性,并提高了读/写性能。

// Enable sharding for 'products' collection
sh.enableSharding("mydb")  
sh.shardCollection("mydb.products", {name: "hashed"})

分片可根据分片密钥将读/写智能地路由到相应的分片。

这些是优化 MongoDB 性能的一些关键技术。适当的索引、覆盖查询、嵌入相关数据和分片可以充分发挥 MongoDB 的潜力。

使用连接池

MongoDB 连接的建立和反复拆卸成本很高。每次数据库操作都要打开一个新连接,可能会造成巨大的性能开销。

连接池通过维护一个可重复使用的连接池,而不是不断地打开和关闭连接,有助于缓解这一问题。

在 MongoDB 中,连接池由驱动程序处理。下面是使用 Node.js 官方驱动程序的示例代码:

// Create MongoClient with connection pooling
const MongoClient = require('mongodb').MongoClient;

const client = new MongoClient(uri, {
  poolSize: 10, // maintain up to 10 connections
  ssl: true,
  auth: {
    user: 'user',
    password: 'pass'
  }
});

// Get a connected client from the pool 
async function run() {
  const db = client.db('mydb');

  // Reuse connections from the pool
  await db.collection('customers').insertOne({name: 'John'});

  await db.collection('orders').find({}).toArray();

  client.close(); 
}

run().catch(console.error);

关键点是:

  • 设置一个poolSize来控制最大连接数
  • 用于client.db()从池中获取数据库连接
  • 驱动程序将有效处理重复使用的连接
  • 不要忘记调用client.close()清理所以这样,我们可以使用连接池来减少连接开销并提高 MongoDB 性能。

使用复制实现冗余

复制通过维护多个数据副本来提供冗余和高可用性。MongoDB 通过包含主节点和辅助节点的副本集复制数据。

下面是一个复制集配置示例:

var replSet = new ReplSet([
  new Mongos({
    _id: 0, 
    host: "mongodb1.example.com",
    priority: 2
  }),
  new Mongos({
    _id: 1,
    host: "mongodb2.example.com"  
  }),
  new Mongos({
    _id: 2,
    host: "mongodb3.example.com"
  })
]);

replSet.initiate();

这定义了一个副本集:

  • 主节点(优先级 2)位于 mongodb1.example.com
  • 两个辅助节点:mongodb2 和 mongodb3
  • 节点 ID 0、1 和 2 要在 Node.js 应用程序中使用它:
// Connect to replica set 
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb://mongodb1.example.com,mongodb2.example.com,mongodb3.example.com/?replicaSet=replSet";

MongoClient.connect(uri, function(err, client) {

  const db = client.db("mydb");

  // Read/write to primary
  db.collection("customers").find(...); 
  db.collection("orders").insertOne(...);

});

它连接到副本集,并自动将读/写指向主节点。如果主节点宕机,驱动程序会处理故障切换。

以上就是这篇文章的全部内容了,如果您觉得有帮助 请三连哦!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论