Tôi có một câu hỏi rất đơn giản mà trong SQL
thể được biểu diễn như sau:Tối ưu hóa Slick tạo truy vấn 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;
Tôi đã rất ngạc nhiên khi sử dụng Slick DSL
để đại diện cho trên truy vấn, truy vấn được tạo ra từ sau 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)
}
Nhìn như sau:
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;
Tôi đang làm gì sai? Việc xem các truy vấn lồng nhau như vậy có bình thường không? Điểm sử dụng Slick DSL là gì nếu độ phức tạp của truy vấn tăng nhanh? Tôi có lẽ có thể viết bản địa SQL
tuy nhiên tôi thực sự thích Slick DSL
. Các kỹ thuật tối ưu hóa các truy vấn Slick
là gì?
Tôi chưa thử phiên bản cụ thể này nhưng có thể là 3.1.0-M2 hữu ích trong việc tránh truy vấn phụ. http://slick.typesafe.com/news/2015/08/13/slick-3.1.0-M2-released.html. Điểm nhấn chính của phát hành mốc "Trình biên dịch truy vấn mới back-end. Mục tiêu chính là tránh các truy vấn phụ bất cứ khi nào có thể. Phiên bản hiện tại là tính năng hoàn chỉnh." –
Cảm ơn, tôi sẽ cung cấp cho nó một đi và tôi sẽ cập nhật ngay. –
Nếu bạn đang sử dụng MySQL, thì đó là một vấn đề đã biết. https://github.com/slick/slick/issues/489. Slick-3.1.0 sẽ tạo ra các truy vấn tốt hơn. – mohit