Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to efficiently write DISTINCT query in Django with table having foreign keys
    primarykey
    data
    text
    <p>I want to show distinct cities of Users in the front end dropdown. For that, i make a db query which fetches distinct <code>city_name</code> from table <code>City</code> but only those cities where users are present. </p> <p>Something like below works for a small size of <code>User</code> table, but takes a very long time if <code>User</code> table in of size 10 million. Distinct cities of these users are still ~100 though.</p> <pre><code>class City(models.Model): city_code = models.IntegerField(unique=True) city_name = models.CharField(max_length=256) class User(models.Model): city = models.ForeignKey('City', to_field='city_code') </code></pre> <p>Now i try to search distinct city names as:</p> <pre><code>City.objects.filter().values_list('city__city_name').distinct() </code></pre> <p>which translates to this on PostgreSQL:</p> <pre><code>SELECT DISTINCT "city"."city_name" FROM "user" LEFT OUTER JOIN "city" ON ("user"."city_id" = "city"."city_code"); </code></pre> <p>Time: 9760.302 ms</p> <p>That clearly showed that PostgreSQL was not making use of index on 'user'.'city_id'. I also read about a workaround solution <a href="http://zogovic.com/post/44856908222/optimizing-postgresql-query-for-distinct-values" rel="nofollow">here</a> which involved writing a custom SQL query which somehow utilizes index.</p> <p>I tried to find distinct 'user'.'city_id' using the above query, and that actually turned out to be pretty fast.</p> <pre><code>WITH RECURSIVE t(n) AS (SELECT min(city_id) FROM user UNION SELECT (SELECT city_id FROM user WHERE city_id &gt; n order by city_id limit 1) FROM t WHERE n is not null) SELECT n FROM t; </code></pre> <p>Time: 79.056 ms</p> <p>But now i am finding it hard to incorporate this in my Django code. I still think it is a kind of hack adding custom query in the code for this. But a bigger concern for me is that the column name can be totally dynamic, and i can not hardcode these column names (eg. city_id, etc.) in the code.</p> <pre><code>#original_fields could be a list from input, like ['area_code__district_code__name'] dataset_klass.objects.filter().values_list(*original_fields).distinct() </code></pre> <p>Using the custom query would need atleast splitting the field name with '__' as delimiter and process the first part. But it looks like a bad hack to me.</p> <p>How can i improve this? </p> <p>PS. The <code>City</code> <code>User</code> example is just shown to explain the scenario. The syntax might not be correct.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload