近期对couchbase 的n1ql 扩展进行了一次探索性的试验,有以下几点认识。
1. 安装
a) PHP EXT >= 2.0,PHP >= 5.0
b) Couchbase Server >= 4.5.1 ,最好使用最新版本。
c) Couchbase Server 安装过程中应 必须开启 Query、Index、Data,这三个服务即为N1QL的必要组件
2. 语法
a) 首先在Bucket上创建一个PRIMARY 索引,否则无法进行查询
b) N1QL 的查询语法,基本上和RDMS的语句保持一致,开发者的目的是为了让用户能够快速对接N1QL,而无须在其语法学习上花费更多的时间成本,经测试发现当 查询语句中涉及到 辅助函数时,会有很大的差异,这个在实际应用中还需查询官方文档.
c) where条件的IN语句的写法为:'field' in ['sfa', 'dafda'] 这与mysql 是不同的。
d) 数据的存储形式时json格式,查询时字段类型有两种,要么数据 要么字符串,如:
存储文当为:{"id": "1"} {"id": 2}
语句 select * from bucket where id = 1 , 结果为: 空
语句 select * from bucket where id = '1' , 结果为: {"id": "1"}
3. 索引
a) 索引类型分两种 GSI、VIEW,默认为GSI类型。
b) 架构,查询首先在索引节点上查询,如果不满足条件再到 数据服务器节点中获取
c) 创建。 在本地windows主机上测试,每秒钟索引服务器高峰时可创建3000+个索引(这意味着 可以查询到 最近一秒内刚刚存储进来的3000个文档)。当然这个指标的大小是取决于RAM和CPU的大小和性能好坏的。所以对于一些小型对实时性要求不严格的系统,N1QL完全可以充当独立数据库使用
d) 空间占用。 索引文件和数据源文件的存储空间占用大小比例大概在 3:1,如果这个数据源文件有n个索引文件 ,而源文件的大小是1MB的话,那么粗略估算空间占用为 n* 3 * 1 (MB)。(注:这个比例大小主要取决于索引列的大小)
e) 性能。
->. 随着索引文件的逐步增长,查询效率会逐步变差,所以在实际使用中有两种解决方案:创建索引会考虑增加 where条件, 来进一步增加索引文件的粒度(有点类似mysql的分区) 参考语法:
CREATE INDEX index_name ON bucket_name( index_key1, ..., index_keyN)
WHERE index_filter
USING GSI | VIEW;
WITH { "nodes": [ "node1:8091" ] }
或者, 增加索引镜像节点,进行负载均衡。
->. 性能最好的情况是查询的字段全部为索引字段的子集。
测试数据为80万+
索引覆盖查询,耗时20ms , 而mysql 耗时4ms
当执行统计时,即使是使用了覆盖索引,如下是 explain SQL的结果 (cover 表示完全使用索引)
但查询性能令人沮丧,耗时一分钟
如果增加 order by asc | desc 子句,那么其性能会更差,有时候多达3分钟之多
官方论坛的解释如下(https://forums.couchbase.com/t/explicitly-selecting-an-index-to-use/2468/8):
note that indexes are used to process WHERE clauses. They are not used to process ORDER BY clauses. You cannot specify the order in which N1QL processes records; you can only specify the order in which it produces output results, using the ORDER BY clause.
基于以上原因,我们提前创建一个有序建索引,那么在查询时 就不涉及 order 子句了,但是,会有另外的问题,当我们的查询场景很复杂或变化非常多时,就必须针对每个查询语句来创建对应的索引,这时索引文件将会很多。这样的使用方式,有点类似RDMS的视图。
总结: 我个人感觉N1QL 适合那些特定数据查询方式的数据源,这样可以实现像使用关系型数据库一样方便的操作key/Value 数据库