当我们在Couchbase
数据库上进行基准测试时,我们试图比较按他们的id / key
搜索项目和通过使用二级索引的查询搜索项目。
在Couchbase中有关indexing and performance的这篇文章之后,我们认为两者的性能是相同的。
但是,在我们的测试中,我们发现有时key/id
进行的搜索要比使用二级索引的搜索快得多。
例如使用索引约3MS进行搜索,按键约0.3MS(这是10倍)
要点是,这种差异并不构成。键搜索范围从0.3MS到15MS。
我们想知道是否:
答案 0 :(得分:3)
您得到的结果与我期望的一致。当您使用ID进行任何操作时,Couchbase都将用作键值存储。键值存储大约是一个大的分布式哈希图,在这种数据结构中,使用id时,可以在get / save / delete上获得很好的性能。
每当您存储新文档时,couchbase会对密钥进行哈希处理并为其分配虚拟存储桶(类似于分片)。当您需要取回该文档时,它会使用相同的算法来找出该文档位于哪个虚拟存储桶中,因为SDK具有群集映射,并且确切知道哪个节点具有哪些分片,因此您的应用程序将直接向该文档请求拥有它的节点。
另一方面,当您查询数据库时,Couchbase必须在内部进行映射/归约以找出文档的位置,这就是为什么通过id进行操作更快的原因。
关于从0.3ms到15ms的结果问题,如果不调试环境就很难说出来。但是,有许多因素可能对此有所贡献。例如:文档已缓存/未缓存,节点尺寸过小等。
答案 1 :(得分:3)
要添加到@deniswrosa的答案中,辅助索引将始终变慢,因为首先必须根据您的查询遍历索引以找到文档密钥,然后执行密钥查找。如果您已经拥有密钥,则仅执行密钥查找会更快。遍历索引的工作量可能会有所不同,具体取决于索引的选择性程度,整个索引是否在内存中等等。如果您有足够的内存来支持整个索引,则内存优化的索引可以确保整个索引都在内存中
当然,如果有问题的文档不在缓存中,并且需要将其从存储设备中带入内存中,那么即使是简单的键查找也可能会变慢。
答案 2 :(得分:1)
可以大规模实现亚毫秒级的二级查找,但需要对查询,索引以及Couchbase的一些系统参数进行一些调整。考虑以下简单示例:
在userBucket中采样文档:
“用户:: 000000000001”:{ “ email”:“ benjamin1@couchbase.com”, “ userId”:“ 000000000001” }
此查询:
SELECT userId 来自userBucket 哪里 电子邮件=“ benjamin1@couchbase.com” AND userId不为空 ;
...应该能够通过适当调整的二级索引来实现亚毫秒级的性能:
在userBucket(email,userId)上创建索引idx01;
由于索引完全覆盖了查询,因此查询引擎无需从K / V存储中获取文档。但是,“ SELECT * ...”将始终导致查询服务获取文档,因此比简单的k / v GET(“ user :: 000000000001”)慢。
为了获得最佳延迟,请确保查看您的查询计划(使用EXPLAIN语法),并确保您的查询不是FETCHING。 https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/explain.html