You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Google Spanner的readUsingIndex方法中指定WHERE条件?

在Google Spanner的readUsingIndex中指定WHERE条件

你完全不需要在遍历ResultSet的时候手动过滤行!Google Spanner的Java客户端提供了两种直接在读取阶段指定过滤条件的方式,适配不同的场景:

1. 针对索引主键列的简单过滤(用KeySet)

readUsingIndex方法是基于索引的键来实现高效读取的,所以如果你的WHERE条件是针对索引的主键列(也就是你创建AlbumsByAlbumTitle2时指定的索引列,比如AlbumTitle),可以通过KeySet来精准指定过滤规则:

示例1:精确匹配某值

比如要查询AlbumTitle = 'Thriller'的行,替换原来的KeySet.all()为KeySet.singleKey():

static void readStoringIndexWithExactMatch(DatabaseClient dbClient) {
    try (ResultSet resultSet = dbClient
            .singleUse()
            .readUsingIndex(
                    "Albums",
                    "AlbumsByAlbumTitle2",
                    // 对应WHERE AlbumTitle = 'Thriller'
                    KeySet.singleKey(Key.of("Thriller")),
                    Arrays.asList("AlbumId", "AlbumTitle", "MarketingBudget"))) {
        while (resultSet.next()) {
            System.out.printf(
                    "%d %s %s\n",
                    resultSet.getLong(0),
                    resultSet.getString(1),
                    resultSet.isNull("MarketingBudget") ? "NULL" : resultSet.getLong("MarketingBudget"));
        }
    }
}

示例2:范围匹配

如果要查询AlbumTitle介于"Acoustic"和"Jazz"之间的行,可以用KeySet.range():

static void readStoringIndexWithRange(DatabaseClient dbClient) {
    // 对应WHERE AlbumTitle >= 'Acoustic' AND AlbumTitle <= 'Jazz'
    KeySet keySet = KeySet.range()
            .start(Key.of("Acoustic"))
            .end(Key.of("Jazz"))
            .build();

    try (ResultSet resultSet = dbClient
            .singleUse()
            .readUsingIndex(
                    "Albums",
                    "AlbumsByAlbumTitle2",
                    keySet,
                    Arrays.asList("AlbumId", "AlbumTitle", "MarketingBudget"))) {
        while (resultSet.next()) {
            System.out.printf(
                    "%d %s %s\n",
                    resultSet.getLong(0),
                    resultSet.getString(1),
                    resultSet.isNull("MarketingBudget") ? "NULL" : resultSet.getLong("MarketingBudget"));
        }
    }
}

2. 复杂条件过滤(用SQL查询+强制索引)

如果你的WHERE条件涉及非索引主键列(比如MarketingBudget),或者需要更复杂的逻辑(AND/OR组合、比较运算符等),直接使用SQL查询会更灵活,同时可以通过@{FORCE_INDEX=索引名}来强制Spanner使用你指定的存储索引,保证读取效率:

static void queryWithComplexCondition(DatabaseClient dbClient) {
    String sql = "SELECT AlbumId, AlbumTitle, MarketingBudget " +
                 "FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle2} " +
                 "WHERE MarketingBudget > 10000 AND AlbumTitle LIKE 'Rock%'";
    try (ResultSet resultSet = dbClient.singleUse().executeQuery(Statement.of(sql))) {
        while (resultSet.next()) {
            System.out.printf(
                    "%d %s %s\n",
                    resultSet.getLong(0),
                    resultSet.getString(1),
                    resultSet.isNull("MarketingBudget") ? "NULL" : resultSet.getLong("MarketingBudget"));
        }
    }
}

总结

  • 简单的索引列过滤:用KeySet配合readUsingIndex,性能最优;
  • 复杂条件或非索引列过滤:用SQL查询+强制索引,灵活性更高。

内容的提问来源于stack exchange,提问作者Aditya Rewari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:32:36