我想選擇3個最近發佈的項目,與任何標籤類似的當前項目(和其他一些過濾器太) 找不到有效的方式來做到這一點,有數據庫中有很多'item'。django taggit similar_objects非常緩慢的查詢
from taggit_autosuggest.managers import TaggableManager
class Item(models.Model):
publish_date = DateField()
tags = TaggableManager()
sites = ManyToManyField(Site)
def my_view():
...
current_item = #get current item
related_items = Item.active_objects.filter(
sites=current_site,
id__in=[x.id for x in current_item.tags.similar_objects()]
).order_by('-publish_date')[:3]
...
但是,這會導致相當大的性能問題,從similar_objects()方法。成倍的多個標籤越差current_item具有
# Query_time: 20.613503 Lock_time: 0.000182 Rows_sent: 83 Rows_examined: 7566504
SELECT `taggit_taggeditem`.`content_type_id`, `taggit_taggeditem`.`object_id`, COUNT(`taggit_taggeditem`.`id`) AS `n` FROM `taggit_taggeditem` WHERE (NOT (`taggit_taggeditem`.`object_id` = 205636 AND `taggit_taggeditem`.`content_type_id`
= 11) AND (`taggit_taggeditem`.`tag_id`) IN (SELECT DISTINCT `taggit_tag`.`id` FROM `taggit_tag` INNER JOIN `taggit_taggeditem` ON (`taggit_tag`.`id` = `taggit_taggeditem`.`tag_id`) WHERE (`taggit_taggeditem`.`object_id` = 205636 AND
`taggit_taggeditem`.`content_type_id` = 11))) GROUP BY `taggit_taggeditem`.`content_type_id`, `taggit_taggeditem`.`object_id` ORDER BY `n` DESC;
我也試着不使用類似物體的方法
related_items = Item.active_objects.filter(
sites=current_site,
tags__in=current_item.tags.all()).exclude(slug=slug).order_by('-publish_date').distinct()[:3]
context['tagged'] = tags.order_by('-publish_date').distinct()[:3]
這是一貫糟糕的(一些查詢高達120秒,呸)
什麼是「好」的方法來做到這一點?!
是的,但重點是要避免similar_objects()方法。因爲這是上面查詢的原因,所以指數級差,當前故事的標籤越多 – straykiwi 2015-04-01 03:36:52
您提供的查詢具有與''__in'''一起使用的similar_objects()調用。如果''''''''''''''''''''''''''會返回很多'''''''''將要執行的對象。我建議使用連接而不是''''''''。試試看看它是如何工作的。 – schillingt 2015-04-01 11:28:06
http://django-taggit.readthedocs.org/en/latest/api.html#TaggableManager.similar_objects 原因是因爲similar_objects返回的不是查詢集列表。如果你看一下實現,那很糟糕。 我想出了一個更好的解決方案,但它不是一件藝術品,所以我不會接受它,以防萬一有更好的東西出現 – straykiwi 2015-04-01 20:24:53