优化 Slick 生成的 SQL 查询
Optimizing Slick generated SQL query
我有一个非常简单的查询,在 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
查询的技巧是什么?
既然你已经写过你正在使用 PostgreSQL,那么我就不用担心,因为 PostgreSQL 以非常好的查询优化器而闻名。这种简单的转换毫不费力,几乎不需要额外的时间。唯一的事情就是你等待,问题最终会在上游解决(Slick 3.1 版左右),你不需要做任何事情。
p.s.: 你为什么不简单地使用这个查询?它应该 return 完全相同的结果,如果你对表有外部约束:
SELECT id, COUNT(*) FROM cart_product WHERE id=3
我有一个非常简单的查询,在 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
查询的技巧是什么?
既然你已经写过你正在使用 PostgreSQL,那么我就不用担心,因为 PostgreSQL 以非常好的查询优化器而闻名。这种简单的转换毫不费力,几乎不需要额外的时间。唯一的事情就是你等待,问题最终会在上游解决(Slick 3.1 版左右),你不需要做任何事情。
p.s.: 你为什么不简单地使用这个查询?它应该 return 完全相同的结果,如果你对表有外部约束:
SELECT id, COUNT(*) FROM cart_product WHERE id=3