2015-08-15 18 views
17

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ì?

+0

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." –

+0

Cảm ơn, tôi sẽ cung cấp cho nó một đi và tôi sẽ cập nhật ngay. –

+0

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

Trả lời

4

Vì bạn đã viết bạn đang sử dụng PostgreSQL, sau đó tôi sẽ không lo lắng, vì PostgreSQL được biết đến với một trình tối ưu hóa truy vấn thực sự tốt. Biến đổi đơn giản như vậy là dễ dàng, nó hầu như không mất thêm thời gian. Điều duy nhất là bạn chờ đợi, vấn đề cuối cùng sẽ được cố định ngược dòng (một nơi nào đó xung quanh Slick phiên bản 3.1) và bạn không phải làm bất cứ điều gì.

p.s .: Tại sao bạn không chỉ đơn giản sử dụng truy vấn này? Nó phải trả lại chính xác kết quả tương tự, nếu bạn có một ràng buộc nước ngoài trên các bảng:

SELECT id, COUNT(*) FROM cart_product WHERE id=3 
+1

Hãy hy vọng '3.1' sẽ sửa chữa truy vấn lồng nhau. –

Các vấn đề liên quan