[英]SQL query on one to many relationship with multiple filters
我有一些SQL的經驗,但我仍然無法找到如何有效地執行以下查詢性能。
我有2張桌子 - Box
和Item
。 Box
有id
屬性,它是主鍵(還有一些),而Item
有box_id
, type
, name
。 每個表都有數十億條記錄,每個框平均有10個項目。 我想查詢具有至少一個具有給定類型的項目的所有框,以及至少一個具有給定名稱的項目(可以是相同的項目或不同的項目)。 查詢應該以頁面大小為10進行分頁。我對所有Item
屬性使用單列索引。 以下查詢(第一頁)需要很長的時間(超過一分鍾):
SELECT Box.id FROM Box WHERE (EXISTS (SELECT 1 FROM Item WHERE Item.box_id = Box.id AND Item.type = 'my_type')) AND (EXISTS (SELECT 1 FROM Item WHERE Item.box_id = Box.id AND Item.name = 'my_name')) LIMIT 10
我認為問題是在查詢的每個部分中過濾框之間的交集(僅使用其中一個約束查詢返回大約百萬條記錄)。 我正在使用Aurora PostgreSQL 9.6.6。
您沒有回復澄清,所以我會假設一些事情:
Item.name = 'my_name'
Item
表的所有列的單列索引。 id
是主鍵,因此它已經有一個索引。 現在,我的看法是您使用的索引對於此查詢不是最佳的,因為它們僅包含列。 如果您還沒有它們,請嘗試創建以下索引:
create index ix1 on Item (box_id, type);
create index ix2 on Item (box_id, name);
是的,他們兩個。 再次嘗試查詢,看看需要多長時間。
如果仍然很慢,請發布解釋計划,使用:
EXPLAIN ANALYZE
SELECT Box.id
FROM Box
WHERE
(EXISTS (SELECT 1 FROM Item WHERE Item.box_id = Box.id AND Item.type = 'my_type'))
AND
(EXISTS (SELECT 1 FROM Item WHERE Item.box_id = Box.id AND Item.name = 'my_name'))
INTERSECT
是另一種選擇。
SELECT Box_id FROM Item
WHERE Item.type = 'my_type'
INTERSECT
SELECT Box_id FROM Item
WHERE Item.name = 'my_name'
注意:INTERSECT返回不同的值,因此不需要外部查詢來獲取符合條件的不同Box_id值的列表。 此查詢確實返回了孤立項(box_id不在box表中的項),因此如果是這種情況,可能需要外部查詢。
像這樣的東西?
SELECT DISTINCT ON (Box.id) Box.*
FROM Box
JOIN Item I1 ON I1.box_id = Box.id AND I1.type = 'my_type'
JOIN Item I2 ON I2.box_id = Box.id AND I2.name = 'my_name'
ORDER BY Box.id;
JOIN
按項目的類型和名稱過濾結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.