LIKE语句中的查询参数导致响应缓慢

问题描述 投票:2回答:1

我正在尝试使用node.js客户端库查询带有查询参数的Google扳手。但是,查询参数的响应速度比没有查询参数的响应慢得多。查询具有LIKE(前向匹配)语句。我找不到使用LIKE语句使用查询参数的推荐方法。

另外,我用相同的语句测试,查询与参数和查询没有参数没有区别。

表有超过2000万行。实例是1个节点。

有什么解决方案吗?或者这是谷歌扳手的错误?

Schema的一部分(实际上超过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
})();

谢谢您的帮助!

node.js google-cloud-platform google-cloud-spanner google-cloud-node
1个回答
4
投票

这是目前Cloud Spanner的限制。通过LIKE模式的常量值,Cloud Spanner能够在查询编译期间基于LIKE模式优化查找表达式。例如,在这种情况下,Cloud Spanner将能够生成具有基本查找表达式的查询计划

STARTS_WITH(props__address_quadkey, 1330020303011010200)

这将能够有效地搜索索引中与LIKE模式中的前缀匹配的条目。

但是使用参数化的LIKE模式,这是不可能的,因为参数直到执行时才被评估并且可以包含任何LIKE表达式。因此,Cloud Spanner必须读取所有行并根据参数中的LIKE模式对其进行评估,以过滤掉不匹配的行,而不是能够有效地查找匹配的行。

但是,此限制不会影响更简单的谓词,例如等式谓词,其中Cloud Spanner能够根据参数的值进行有效的查找。

© www.soinside.com 2019 - 2024. All rights reserved.