簡體   English   中英

使用group_concat標記查詢

[英]Tagging query with group_concat

使用數據庫模式來標記此問題的已接受答案是否可以使用可處理大量數據的group_concat進行查詢? 我需要為所有標記為標記x的項目獲取帶有標簽的項目。 使用具有約.5百萬個標簽的group_concat的查詢在> 15秒時非常慢。 沒有group_concat( 沒有標簽的項目)它是~0.05秒。

作為一個附帶問題,SO如何解決這個問題?

這可能是一個糟糕的索引策略的情況。 調整您鏈接的問題的接受答案中顯示的架構:

CREATE Table Items (
  Item_ID    SERIAL,
  Item_Title VARCHAR(255),
  Content    TEXT
) ENGINE=InnoDB;

CREATE TABLE Tags (
  Tag_ID     SERIAL,
  Tag_Title  VARCHAR(255)
) ENGINE=InnoDB;

CREATE TABLE Items_Tags (
  Item_ID    BIGINT UNSIGNED REFERENCES Items (Item_ID),
  Tag_ID     BIGINT UNSIGNED REFERENCES Tags  ( Tag_ID),
  PRIMARY KEY (Item_ID, Tag_ID)
) ENGINE=InnoDB;

注意:

  • MySQL的SERIAL數據類型是BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的別名,因此被索引;

  • Items_Tags定義外鍵約束會在外鍵列上創建索引。

我建議在規范化數據和非規范化數據之間進行混合。
因此,使用eggyal提供的規范化結構,我將執行以下非規范化結構:

CREATE TABLE Items_Tags_Denormalized (
  Item_ID    BIGINT UNSIGNED REFERENCES Items (Item_ID),
  Tags     BLOB,
  PRIMARY KEY (Item_ID)
) ENGINE=InnoDB;

在列Tags您將擁有相應Item_ID所有標簽( Tag_Title )。
現在你有兩種方法來實現這個目標:

  • 創建一個定期運行的cron,它將構建此表Items_Tags_Denormalized使用GROUP_CONCAT或任何適合你的東西(優點:當你在Items_Tags表中插入或刪除時不會產生額外的負載;缺點:非規范化表並不總是最新的(取決於關於你多久運行一次cron))

  • 在插入和刪除時為Items_Tags表創建觸發器以保持最新的Items_Tags_Denormalized表(優點:非規范化表將始終是最新的;缺點:在Items_Tags表中插入或刪除時的額外負載)

考慮到優點和缺點,選擇最適合您需求的解決方案。

因此,最后您將擁有Items_Tags_Denormalized表,您只能在不執行其他操作的情況下閱讀該表。

為什么要使用group_concat呢? 對於給定的標簽x,您說選擇項目列表很快。 對於給定的項目列表,獲取所有標簽也應該很快。 並且通常沒有某種限制,我的意思是普通網站不會在一個頁面上顯示100000個條目。

我會建議:

drop temporary table if exists lookup_item;

create temporary table lookup_item (item_id serial, primary key(item_id));

insert into lookup_item select i.id as item_id 
from items i 
where exists (select * from items_tags where item_id = i.id and tag_id = <tag_id>)
and <other conditions or limits>;

select * from lookup_item
inner join items_tags it on it.item_id = i.id
inner join tags t on t.id = it.tag_id
order by i.<priority>, t.<priority>

優先級可以針對項目進行最后修改,並對標簽具有某種重要性。

然后你用它的標簽得到每個項目。 代碼中唯一的工作是查看結果行何時具有下一個項目。

如果我理解正確的話, GROUP_CONCAT並不是你唯一要刪除的東西,它使得查詢更快,沒有標簽。 GROUP_CONCAT您選擇了Tags.Tag_Title並強制訪問Tags表。

您可以嘗試使用Items_Tags.Tag_ID運行GROUP_CONCAT來測試我的理論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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