2009-12-30 4 views
1

У меня есть три модели: продукт, категория и место. Продукт имеет отношение ManyToMany к категории и месту. Мне нужно получить список категорий, по крайней мере, по продукту, соответствующему определенному месту. Например, мне может потребоваться получить все категории, в которых есть хотя бы один продукт из Бостона.- отличный дорогой запрос в django?

У меня есть 100 категорий, 500 мест и 100 000 изделий.

В sqlite с продуктами 10K запрос занимает ~ секунду. В производстве я буду использовать postgresql.

Я использую:

categories = Category.objects.distinct().filter(product__place__name="Boston") 

ли этот запрос будет дорого? Есть ли лучший способ сделать это?

Это результат connection.queries

{'time': '0.929', 'sql': u'SELECT DISTINCT "catalog_category"."id", "catalog_category"."name" FROM "catalog_category" INNER JOIN "catalog_product_categories" ON ("catalog_category"."id" = "catalog_product_categories"."category_id") INNER JOIN "catalog_product" ON ("catalog_product_categories"."product_id" = "catalog_product"."id") INNER JOIN "catalog_product_places" ON ("catalog_product"."id" = "catalog_product_places"."product_id") INNER JOIN "catalog_place" ON ("catalog_product_places"."car_id" = "catalog_car"."id") WHERE "catalog_place"."name" = Boston ORDER BY "catalog_category"."name" ASC'}] 

Благодаря

ответ

0

Это проблема не только Django; DISTINCT медленнее для большинства реализаций SQL, потому что это относительно сложная операция. Here - хорошее обсуждение того, почему в Postgres это происходит медленно.

Одним из способов обработки этого было бы использовать отличный Django caching mechanism по этому запросу, считая, что результаты не меняются часто, а незначительная неподвижность не является проблемой. Другой подход состоял бы в том, чтобы сохранить отдельный список только отдельных категорий, возможно, в другой таблице.

+1

Ссылка на механизм кеширования Django нарушена, но только добавление одного символа слишком мало, видимо, редактирование. Это просто отсутствует трейлинг «e». Это должно быть: http://docs.djangoproject.com/en/dev/topics/cache – andrewsomething

-1

Хотя Chase прав, что DISTINCT - это, как правило, медленная операция, в этом случае это также совершенно бессмысленно. Как вы можете видеть из сгенерированного SQL, DISTINCT выполняется по комбинации ID и имени - которые никогда не будут дублироваться в любом случае. Поэтому нет необходимости в вызове distinct() в этом запросе.

Как правило, Django не возвращает повторяющиеся результаты от простого фильтра. Основное время, когда distinct() полезно, - это когда вы обращаетесь к соответствующему набору запросов через отношения ManyToMany или ForeignKey, где несколько элементов могут быть связаны с одним и тем же экземпляром, а отдельные будут удалять дубликаты.

+2

Я получаю дубликаты результатов в этом случае, если я не использую отдельные(), и я делаю имеют отношения ManyToMany. Разве я что-то не хватает и что-то не так? – pablo