我正在尝试使用node.js客户端库使用查询参数查询Google扳手。 但是,使用查询参数的响应比没有查询参数的响应要慢得多。 查询具有LIKE(前向匹配)语句。我找不到在LIKE语句中使用查询参数的推荐方法。
另外,我用相等的语句进行了测试,有参数的查询和无参数的查询之间没有区别。
表有超过2000万行。实例是1个节点。
有什么解决办法吗?还是Google扳手出现此错误?
部分架构(实际上超过40列):
CREATE TABLE props (
props__id STRING(MAX) NOT NULL,
props__address_quadkey STRING(MAX),
...
) PRIMARY KEY (props__id)
索引:
CREATE INDEX props__address_quadkey
ON props (
props__address_quadkey
)
测试代码:
const Spanner = require('@google-cloud/spanner');
const spanner = new Spanner();
const db = spanner
.instance('instance_name')
.database('database_name');
(async () => {
// Make connection
await db.run({ sql: 'SELECT 1' });
console.time('Without param');
const r1 = (await db.run({
sql: `
SELECT
props__id
FROM props@{FORCE_INDEX=props__address_quadkey}
WHERE
(props__address_quadkey LIKE '1330020303011010200%')
`
}))[0];
console.log(r1.length); // 121
console.timeEnd('Without param'); // Without param: 277.223ms
console.time('with param 1');
const r2 = (await db.run({
sql: `
SELECT
props__id
FROM props@{FORCE_INDEX=props__address_quadkey}
WHERE
(props__address_quadkey LIKE @quadkey)
`,
params: { quadkey: '1330020303011010200%' },
types: { quadkey: 'string' },
}))[0];
console.log(r2.length); // 121
console.timeEnd('with param 1'); // with param 1: 9240.822ms
})();
谢谢您的帮助!
答案 0 :(得分:4)
当前是Cloud Spanner的限制。借助LIKE
模式的恒定值,Cloud Spanner能够在查询编译期间基于LIKE
模式优化查找表达式。例如,在这种情况下,Cloud Spanner将能够使用基本上为
STARTS_WITH(props__address_quadkey, 1330020303011010200)
,它将能够有效地在索引中搜索与LIKE
模式中的前缀匹配的条目。
但是对于参数化的LIKE
模式来说,这是不可能的,因为该参数要等到执行时间后才能评估,并且可以包含任何LIKE
表达式。结果,Cloud Spanner不能有效地查找匹配的行,而必须读取所有行并根据参数中的LIKE
模式对其进行评估,以过滤出不匹配的行。
但是,此限制不会影响更简单的谓词,例如相等谓词,其中Cloud Spanner能够基于参数的值进行有效的查找。