客户想知道 在Google App Engine 平台中,查询性能如何 ?
所以我用GaeLyk (一个基于Groovy的轻量级 GAE开发框架) 编写了一个非常简单的测试
测试用例:
4种类型 (Kind)
椅子制造部门 ChairMakingDeparts [ Key,name,parentDept ]
椅子 Chair [Key ,name,dept ] dept 为外键(关联到部门)
房间 Room [Key ,name,chairList ]
Root Root [Key,deptList,chairList,roomList] 一个对象字段类型为ListType ,存储前三种对象所有的Key
其中,我们初始化数据,创建 n 个部门 同时,为每个部门创建所对应的椅子:类似
Furniture department
-- Chairmaking department 0 -> chair no 0
-- Chairmaking department 1 -> chair no 1
-- Chairmaking department 2 -> chair no 2
-- Chairmaking department 3 -> chair no 3
..........................10000 .........10000
至于 Room 类似:
add room like
name chairList
room 0 [chair0]
room 1 [chair0,chair1]
room 2 [chair0,chair1,chair2]
.......
romm 99[chair0,,,,,chair99]
并且把对象的Key push 到Root的字段中
然后支持两种查询方式:
第一种,利用GAE 的 IN filter完成对于Chair 的查询,类似与 : SELECT * FROM Chairs WHERE dept in (1,2,3,4,5,6…… 的方式
第二种,利用GAE 的 ListType 完成对于Room的查询,基本上通过一椅子查询到多个部门
前一个随笔中的(ListType . Equals filter)
类似与 : SELECT * FROM Rooms WHERE chairList equals(chair100)
结果查询性能都不理想:

目前的 在 Google App Enine 测试地址:
http://zhou-xiang.appspot.com/listquery/index.groovy
用于查询的Groovy代码 :
GAE 上运行Groovy 不支持 List 类型 .size 用法,必须要 .size().
package listquery
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.
*
import static com.google.appengine.api.datastore.FetchOptions.Builder.
*
import entities.
*
;
def root;
def resultCount
=
0
;
def msg
=
"
No work
"
;
def rootQuery
=
new
Query(ListQueryData.ROOT_KIND_NAME)
PreparedQuery rootPreQuery
=
datastore.prepare(rootQuery)
root
=
rootPreQuery.asSingleEntity();
def beginDate
=
new
Date();
if
(params.queryType
&&
params.queryType.equals(
"
l
"
)){
//
listType rooms query
//
room key
if
(root
&&
params.count){
Integer querySize
=
Integer.valueOf(params.count);
def chairItem
=
querySize
<
root.chairList.size()
?
root.chairList[root.chairList.size()
-
querySize] : root.chairList[
0
];
def roomQuery
=
new
Query(ListQueryData.ROOM_KIND_NAME)
roomQuery.addFilter (
"
chairList
"
, FilterOperator.EQUAL, chairItem)
PreparedQuery roomPreQuery
=
datastore.prepare(roomQuery)
def roomList
=
roomPreQuery.asList(withLimit(
1000
))
resultCount
=
roomList.size();
msg
=
"
find
"
+
resultCount
+
"
rooms by
"
+
params.count
+
"
chairs
"
;
}
}
else
{
//
default is "IN " chairs query
if
(root
&&
params.count){
Integer querySize
=
Integer.valueOf(params.count);
def deptList
=
querySize
<
root.deptList.size()
?
root.deptList.subList(
0
,querySize) : root.deptList;
def chairQuery
=
new
Query(ListQueryData.CHAIR_KIND_NAME)
chairQuery.addFilter (
"
dept
"
, FilterOperator.IN, deptList);
PreparedQuery chairPQuery
=
datastore.prepare(chairQuery)
def chairItem
=
chairPQuery.asList(withLimit(
1000
));
resultCount
=
chairItem.size();
msg
=
"
find
"
+
resultCount
+
"
chairs by
"
+
params.count
+
"
deparments
"
;
}
}
def endDate
=
new
Date();
msg
=
msg
+
"
,spent
"
+
(endDate.getTime()
-
beginDate.getTime())
+
"
ms
"
response.renderJson ([
"
count
"
: resultCount,
"
msg
"
:msg])