تفاوت len و count در Queryset جنگو

با سلام و درود، بدون مقدمه بریم سر اصل مطلب، میخواهیم تعداد obj ها رو به دست بیاریم، دو تا راه حل رایج یکی متد count روی کوئری ست و دیگری len می باشد، بریم ببینیم بهتره از هر کدوم تو چه موقعیتی استفاده بشه:

نکته اول: استفاده از count() و len() به موقعیت که میخواهید از آنها استفاده کنید بسیار مرتبط می باشد.

۱) (حالت ۱) هنگامی که فقط می خواهید تعداد عناصر را بدانید و به هیچ وجه قصد پردازش آنها را ندارید، استفاده از count () شدیدا پیشنهاد میشه، چرا؟

وقتی از queryset.count() استفاده می کنید، منجر به یک کوئری SELECT COUNT(*) FROM some_table می شود، تمامی محاسبات سمت DB صورت میگیره و پایتون فقط نیاز داره که نتیجه را بازیابی کنه با هزینه O(1) .

پس در مواقع (حالت ۱) از len(queryset) استفاده نکنید، این خط کد ابتدا کوئری SELECT * FROM some_table را انجام می دهد، که کل جدول را fetch کند با هزینه O(N) و مموری O(N) نیز برای نگهداری داده ها نیاز دارد. پس بدترین کار ممکن استفاده از len برای مواقع (حالت ۱) است

۲) (حالت ۲) اگر نیاز دارید تا کوئری ست مورد نظر را به هر حال fetch کنید، بهتر است از len() استفاده کنید، چرا که منجر به یک کوئری اضافه count روی پایگاه داده نیم شود.

len() (one db query)

    len(queryset) # SELECT * fetching all the data - NO extra cost - data would be fetched anyway in the for loop

    for obj in queryset: # data is already fetched by len() - using cache
        pass

count() (two db queries!):

    queryset.count() # First db query SELECT COUNT(*)

    for obj in queryset: # Second db query (fetching data) SELECT *
        pass

۳) (حالت ۳) این حالت برای زمانیست که کوئری از قبل fetch شده باشد، در این حالت فرقی نمیکنه از countاستفاده کنید یا len هزینه هر دو آنها o(1) می باشد.

 for obj in queryset: # iteration fetches the data
     len(queryset) # using already cached data - O(1) no extra cost
     queryset.count() # using cache - O(1) no extra db query

 len(queryset) # the same O(1)
 queryset.count() # the same: no query, O(1)

مرجع