繁体   English   中英

MariaDB 参数列表的 CTE 语法

[英]MariaDB CTE syntax for parameter list

我正在尝试用 CTE 替换昂贵的where in...查询。 我以前在其他 sql 方言中做过这个,但无法获得 MariaDB/MySQL 的正确语法。

查询替换

select o from orders as o where o.id in :orderIds

id 的列表是动态的。 它是一个使用 JPA 的 Spring Boot 应用程序。现在我知道我必须使用这样的可选参数创建一个本机查询才能使 CTE 工作:

@Query("select o from orders as o from where o.id in :orderIds", nativeQuery = true)
List<OrderEntity> findOrdersByIds(@Param("orderIds") List<String> orderIds);

在上方您可以看到传入(和使用)的 id 的动态参数列表。

我的问题是关于如何将 orderId 的动态列表插入到 CTE 中。 就像是:

WITH orderIds (id) as (
SELECT * FROM :orderIds // What to type here?
) SELECT o.* FROM orderIds
  INNER JOIN orders o ON o.id = orderIds.id

如您所见,上面的第 2 行是我需要帮助的。 如果你知道怎么做,请告诉我。

所以,我设法得到正确的查询,并进行了比较。 长话短说;博士; where...in query 比 CTE 快,至少在我的测量中是这样。 这是我做的,欢迎反馈。

我创建了一个包含两列的新测试表:

CREATE TABLE `perf_table` (
  `system_id` varchar(255) NOT NULL,
  `textcol` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`system_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我用随机数据填充它(uuid() 和 textcol 中的随机字符串)。 我添加了 10 000 行,在 for 循环中使用此调用:

INSERT INTO perf_table VALUES (UUID(), SUBSTR(MD5(RAND()), 1, 10));

我在代码中创建了一个辅助方法来生成实际的查询字符串,并执行本机查询。 这是 CTE 版本:

WITH cteIds AS ((SELECT '<random-id-1>' AS id) UNION (SELECT '<random-id-2>' AS id))
select p.* from cteIds inner join perf_table p on p.system_id = cteIds.id

这里只使用 2 个 id 只是一个例子,我在代码中动态生成了这个字符串。 这是第一个天真的实现,但它有效。

  1. 尝试使用where...inCTE进行比较。 我从perf_table中选取了 30 个随机值,并对第一个 col(主键)和第二个 col(随机内容)执行了查询。 没有创建索引。

  2. 由于 CTE 慢得多,我还尝试完全创建一个单独的表id_table ,插入 30 个 ID 并在 CTE 中做了一个简单的 select ,因为我怀疑UNION不是最佳方式(?)。

然后查询变为:

WITH cteIds AS (SELECT * from id_table) select p.* from cteIds inner join perf_table p on p.textcol = cteIds.id

同样,这只是一个测试,但仍然没有什么不同。 总而言之,在 10 000 行表中的 30 个随机值上执行where...in大约需要 2 毫秒。 用 CTE 做同样的事情需要 24 毫秒。

我错过了什么明显的东西吗? 我在问,因为差异如此之大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM