簡體   English   中英

SQL查詢與多個過濾器的一對多關系

[英]SQL query on one to many relationship with multiple filters

我有一些SQL的經驗,但我仍然無法找到如何有效地執行以下查詢性能。

我有2張桌子 - BoxItem Boxid屬性,它是主鍵(還有一些),而Itembox_idtypename 每個表都有數十億條記錄,每個框平均有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。

您沒有回復澄清,所以我會假設一些事情:

  • 你想要所有的盒子,而不僅僅是其中的10個盒子。
  • 按名稱比較時會出現拼寫錯誤。 應該是: Item.name = 'my_name'
  • 你說“我已經索引了所有Item屬性。” 我假設您有Item表的所​​有列的單列索引。
  • Box的列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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM