Cloud Spanner在不应该使用二级索引的情况下

时间:2019-01-03 15:26:51

标签: google-cloud-platform google-cloud-spanner

使用主键快速执行的现有查询大大降低了速度(10ms-> 8sec),而没有事先通知,因为现在已自动使用为另一个用例创建的辅助索引。

Cloud-Spanner-Web-Query的“说明”告诉我使用了二级索引。如果我更改顺序(仅出于测试目的)或提供FORCE_INDEX,查询将再次迅速。

我可以使用Cloud Spanner Query Syntax Documentation中记录的 FORCE_INDEX = _BASE_TABLE 来“解决”此问题。

我的问题是:为避免这种影响,我真的必须对每个查询都这样做吗?

这将查询定义与索引定义混合在一起,恕我直言,这不是一件好事。

具有主索引的表:

CREATE TABLE change_history (
    userId INT64 NOT NULL,
    createdAtUnique INT64 NOT NULL,
    itemId STRING(512) NOT NULL,
    newValue FLOAT64 NOT NULL,
    oldValue FLOAT64 NOT NULL,
) PRIMARY KEY (userId, itemId, createdAtUnique DESC)

二级索引:

CREATE INDEX ch_userid_createdatunique_all ON change_history (
    userId,
    createdAtUnique
) STORING (
    newValue,
    oldValue
)

原始查询:

SELECT * FROM change_history WHERE                         
    userId = 2563
    AND itemId = "215414"
    AND createdAtUnique >= 15385766670000000
    AND createdAtUnique <= 15465254670000000 ORDER BY createdAtUnique

我希望查询继续使用为其设计的主键。

但是通过添加辅助索引,查询开始使用该索引而不是主键。

1 个答案:

答案 0 :(得分:4)

在这种情况下,查询优化器决定选择索引,因为1)它覆盖了索引; 2)避免了原始计划中的排序,因为索引包含createdAtUnique的升序排序,这是请求的排序顺序在查询中。但是,对于您的数据分发来说,这是一个糟糕的选择。

通常,对于经过手工调整以获取您认为最佳/良好的特定计划的查询,建议在查询中使用force_indexjoin_type提示来保护在极少数情况下,优化程序可能会选择其他计划。