Параметры запроса в операторе LIKE вызывают медленный ответ

Я пытаюсь запросить гаечный ключ Google с параметрами запроса, используя клиентскую библиотеку node.js. Тем не менее, отклик очень медленный с параметром запроса, чем без параметра запроса. Запрос имеет оператор LIKE(forward match). Я не смог найти рекомендуемый способ использовать параметры запроса с оператором LIKE.

Кроме того, я проверил с равным утверждением, нет никакой разницы между запросом с параметром и запросом без параметра.

Таблица содержит более 20 миллионов строк. И экземпляр 1 узел.

Есть ли решение? или это ошибка с гаечным ключом гугл?

Часть схемы (на самом деле более 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
})();

Спасибо за помощь!

1 ответ

В настоящее время это ограничение Cloud Spanner. С постоянным значением для LIKE Cloud Spanner может оптимизировать выражение поиска на основе LIKE шаблон во время компиляции запроса. Например, в этом случае Cloud Spanner сможет сгенерировать план запроса с выражением поиска, которое в основном

STARTS_WITH(props__address_quadkey, 1330020303011010200)

который сможет эффективно искать в индексе записи, которые соответствуют префиксу в LIKE шаблон.

Но с параметризованным LIKE шаблон, который невозможен, так как параметр не оценивается до времени выполнения и может содержать любые LIKE выражение. В результате, вместо того, чтобы эффективно искать совпадающие строки, Cloud Spanner должен прочитать все строки и сравнить их с LIKE шаблон в параметре для фильтрации несовпадающих строк.

Это ограничение, однако, не влияет на более простые предикаты, такие как предикат равенства, где Cloud Spanner может выполнять эффективный поиск на основе значения параметра.

Другие вопросы по тегам