Tôi có một câu hỏi đơn giản về cách hiệu quả nhất để thực hiện một phép nối cụ thể.Tham gia giữa bảng ánh xạ (giao lộ) với cardinality cụ thể
Thực hiện các ba bảng, tên thật đã được thay đổi để bảo vệ sự vô tội:
Bảng: động vật
animal_id name ... ====================== 1 bunny 2 bear 3 cat 4 mouse
Bảng: thẻ
tag_id tag ================== 1 fluffy 2 brown 3 cute 4 small
Mapping Bảng: animal_tag
animal_id tag_id ================== 1 1 1 2 1 3 2 2 3 4 4 2
Tôi muốn tìm tất cả các động vật được gắn thẻ là 'fluffy', 'màu nâu' và 'dễ thương'. Đó là để nói rằng động vật phải được gắn thẻ với tất cả ba. Trong thực tế, số lượng thẻ bắt buộc có thể thay đổi, nhưng không liên quan đến cuộc thảo luận này. Đây là truy vấn tôi đã đưa ra:
SELECT * FROM animal
JOIN (
SELECT at.animal_id FROM animal_tag at
WHERE at.tag_id IN (
SELECT tg.tag_id FROM tag tg
WHERE tg.tag='fluffy' OR tg.tag='brown' OR tg.tag='cute'
)
GROUP BY at.animal_id HAVING COUNT(at.tag_id)=3
) AS jt
ON animal.animal_id=jt.animal_id
Trên bàn có hàng nghìn động vật và hàng trăm 'thẻ', truy vấn này thực hiện một cách đáng kính ... 10s của mili giây. Tuy nhiên, khi tôi nhìn vào kế hoạch truy vấn (Apache Derby là DB), chi phí ước tính của trình tối ưu hóa là khá cao (9945.12) và kế hoạch khá rộng rãi. Đối với một truy vấn này "đơn giản" tôi thường cố gắng để có được kế hoạch truy vấn với chi phí ước tính của một hoặc hai chữ số.
Vì vậy, câu hỏi của tôi là, có cách nào tốt hơn để thực hiện truy vấn này không? Có vẻ như một truy vấn đơn giản, nhưng tôi đã bị choáng ngợp với bất cứ điều gì tốt hơn.
tôi nghĩ bạn nên sử dụng 'AND' thay vì' OR' trong 'WHERE tg.tag = 'fluffy' HOẶC tg.tag = 'brown' HOẶC tg.tag = 'cute'' –
@johntotetwoo Không có hàng _single_ nào trong 'thẻ' khớp với nhiều hơn một giá trị duy nhất, vì vậy việc sử dụng AND sẽ không tạo ra các hàng phù hợp. –
@BrankoDimitrijevic bạn nói đúng! lỗi của tôi. tôi đang nghĩ gì –