在Google App Engine上用gaelyk编写ListType查询测试
客户想知道 在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
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 测试地址:
用于查询的Groovy代码 :
GAE 上运行Groovy 不支持 List 类型 .size 用法,必须要 .size().
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])