我怎样才能使 UNION ALL 更快?

How can I make UNION ALL faster?

我有一个 Cloud Spanner 查询,它是 UNION ALL 潜在的许多子查询,除了一些随每个子查询而变化的参数外,它们都是相同的:

(SELECT t.FirstName, t.BirthDate FROM Singers AS t WHERE SingerId=2 AND t.LastName="Trentor")
UNION ALL
(SELECT t.FirstName, t.BirthDate FROM Singers AS t WHERE SingerId=3 AND t.LastName="Smith")
UNION ALL
...

执行此查询有时需要几秒钟。我可以做些什么来让它更快吗?

它可能有助于您参数化查询。这也将使您的查询更加简洁。 Spanner 有一个查询缓存,用于存储最近查询的形状,因此如果它看到另一个形状相似的查询,它可以使用相同的执行计划。包含 20 个子查询的 UNION ALL 与包含 21 个子查询的 UNION ALL 具有不同的形状,因此这可能会阻碍缓存。将结构数组(即 n-tuples)作为查询参数传递有点棘手,但这是一种有效的方法:

# bind seq1 to [2,3] in your query parameters
# bind seq2 to ["Trentor","Smith"] in your query parameters

SELECT Singers.FirstName,Singers.BirthDate FROM
 (SELECT *
  FROM
  (SELECT id, x_1 FROM UNNEST(@seq1) AS id WITH OFFSET AS x_1)
  JOIN
  (SELECT name, x_2 FROM UNNEST(@seq2) AS name WITH OFFSET AS x_2)
  ON x_1 = x_2) AS params
JOIN Singers
ON params.id=Singers.SingerId AND params.name=Singers.LastName

生成 params 的内部查询将 seq1 和 seq2 压缩在一起,生成 table 包含来自 seq1 和 seq2 的相关条目。