Google App Engine性能 - 检查对象的存在

时间:2011-07-14 12:44:59

标签: java performance google-app-engine google-cloud-datastore

我正在使用Google App Engine对系统进行编码,我只需将对象放入数据存储区即可。我可以使用datastore.put()方法,但我需要知道该对象是否已存在以计算我拥有的新对象的数量。

据我所知,我有以下选项(假设我将密钥作为属性和实体密钥):

private Entity getEntity(String key)
{
    DatastoreService datastore =
        DatastoreServiceFactory.getDatastoreService();

    // Build a query to select this entity from the database:
    Query q = new Query("MyEntity");
    q.setKeysOnly();
    // Add a filter for the key attribute:
    q.addFilter("key", Query.FilterOperator.EQUAL, key);
    PreparedQuery pq = datastore.prepare(q);
    // Select a single entity from the database
    // (there should be no more than one matching row anyway):
    List<Entity> list = pq.asList(FetchOptions.Builder.withLimit(1));

    if (!list.isEmpty())
        // Return the found entity:
        return list.get(0);
    else
        return null;
}

private Entity getEntity(String key)
{
DatastoreService datastore =
    DatastoreServiceFactory.getDatastoreService();

    // Get a key that matches this entity:
    Key key = KeyFactory.createKey("MyEntity", key);

    try {
        return datastore.get(key);
    } catch (EntityNotFoundException e) {
        // Entity does not exist in DB:
        return null;
    }
}

我倾向于使用第二个,因为它似乎更直接,但我担心它可能不会以这种方式使用,因为它会引发异常,并且可能会产生开销。

哪种方法更适合检查数据库中是否存在实体?

有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

除非您的实体很大并且具有许多属性,否则执行get会更快 - 在这种情况下,仅键查询可能会更快。如果性能在这里可能是一个重要的问题,我会建议基准测试 - 但如果没有,后一种方法更直接。

答案 1 :(得分:1)

如果Entity需要唯一性,如果有多个线程在完全同时访问数据库,那么即使这种检查也不能保证唯一性。

在这种情况下,两个线程都不会看到任何存在,并同时创建新对象。即使是交易也无法防止这种情况发生,因为应用程序不会阻止read之间的访问以确定唯一性,write来保存实体。

我知道这听起来不太可能,但这肯定发生在我们身上,例如当我们运行MapReduce作业以批量更新/创建超过8个分片的大批记录(100k +)时。

保证对象唯一的唯一方法是指定其Key的name属性。这将使数据存储create成为新实体(如果不存在),否则它将update实体存储到最后保存的对象。

所以而不是:

Entity entity = new Entity("MyKind");

这确保每个属性只有一个唯一的实体:

String myPropertyValue = getPropValue();
Entity entity = new Entity("MyKind", myPropertyValue);
ds.put(entity); // Ensures only one Entity per this property value