我关注读取性能,我想知道将索引字段值设为null
是否比给它一个值更快。
我有许多带有状态字段的项目。 status
可以是"pending"
,"invalid"
,"banned"
等等。
我的典型请求是找到status
“ok”(或null)。由于空字段未保存到数据存储区,因此避免使用“无用”的默认值(我可以用null替换)已经是一个胜利。所以我已经有更少的磁盘空间使用。
但是我想知道,因为数据存储区是noSql,它不知道数据结构,并且它不知道缺少列status
。那么如何进行status = null
请求检查?
是否必须检查每行的所有列以查找我的列?还是有一些更聪明的机制?
例如,当我们传递一个明确表示它为null的列时(例如,如果是这种情况),对象(null = Entity,key)是否Objectify尊重这一点并在将字段传递给本机API时将其保留在列表中它是空的?)
主要是哪个请求更有效?
答案 0 :(得分:2)
如果指定应对字段/属性建立索引,则低级API(和Objectify)会存储空值并将其编入索引。对于Objectify,如果要更改此行为,可以指定@Ignore(IfNull.class)或@Unindex(IfNull.class)。您可能会将此与其他数据访问API的文档混淆。
由于GAE只允许您查询索引字段,因此您的问题实际上是:索引空值并查询它们,或查询所有内容并过滤掉非空值是否更好?
这纯粹是一个稀疏性的问题。如果绝大多数记录都包含空值,那么最好查询所有内容并过滤掉您不想手动的记录。少数额外的实体读取可能比更新和存储额外的索引便宜。另一方面,如果空记录只占您数据的一小部分,那么您肯定需要索引。
这种索引困境不是GAE独有的。所有数据库都提出了关于低基数字段的这个问题;只是他们会为你做表扫描(测试和跳过行)。
如果您真的想微调这种行为,请阅读Objectify关于部分索引的文档。
答案 1 :(得分:1)
null也被视为数据存储区中的值,并且索引中将存在空值的条目。 Datastore doc says,"数据存储区分不具有属性的实体和拥有具有空值的属性的实体"
数据存储永远不会检查所有列或所有记录。如果您对此属性建立索引,它将仅从索引获取记录如果未编入索引,则无法通过该属性进行查询。
就查询性能而言,它应该是相同的,但您始终可以进行分析和检查。