【发布时间】:2015-11-08 13:21:03
【问题描述】:
我有一个非常简单的查询,SQL 可以表示如下:
SELECT
c.id,
count(cp.product_id)
FROM cart c LEFT OUTER JOIN cart_product cp ON c.id = cp.cart_id
WHERE c.id = 3
GROUP BY c.id;
当使用Slick DSL 表示上面的查询时,我感到非常惊讶,查询是从以下DSL 生成的:
Cart.joinLeft(CartProduct)
.on { case (c, cp) => c.id === cp.cartId }
.filter { case (c, cp) => c.id === 3 }
.groupBy { case (c, cp) => c.id }
.map { case (c, pr) => (c, pr.length)
}
如下图:
SELECT
x2.x3,
count(1)
FROM (SELECT
x4.x5 AS x3,
x4.x6 AS x7,
x8.x9 AS x10,
x8.x11 AS x12,
x8.x13 AS x14,
x8.x15 AS x16
FROM (SELECT
x17."id" AS x5,
x17."user_id" AS x6
FROM "cart" x17) x4 LEFT OUTER JOIN (SELECT
1 AS x9,
x18."id" AS x11,
x18."cart_id" AS x13,
x18."product_id" AS x15
FROM "cart_product" x18) x8 ON x4.x5 = x8.x13) x2
WHERE x2.x3 = 3
GROUP BY x2.x3;
我做错了什么?看到这样的嵌套查询是否正常?如果查询的复杂性增长得如此之快,那么使用 Slick DSL 有什么意义呢?我可能会写原生的SQL,但我真的很喜欢Slick DSL。优化Slick查询的技巧有哪些?
【问题讨论】:
-
我没有尝试过这个特定的版本,但可能是 3.1.0-M2 有助于避免子查询。 slick.typesafe.com/news/2015/08/13/slick-3.1.0-M2-released.html。里程碑发布的主要亮点“新的查询编译器后端。主要目标是尽可能避免子查询。当前版本功能齐全。”
-
谢谢,我会试一试,我会尽快更新。
-
如果您使用的是 MySQL,那么这是一个已知问题。 github.com/slick/slick/issues/489。 Slick-3.1.0 应该会产生更好的查询。
-
很遗憾没有,我用的是
PostgreSQL。 -
删除连接部分并执行如下查询会发生什么情况:
SELECT cp.cart_id, count(cp.product_id) FROM cart_product cp WHERE cp.cart_id = 3 GROUP BY cp.cart_id;它会改变执行计划吗?