Django N+1 Problemi ve Çözüm Önerisi

Herkese merhaba arkadaşlar, öncelikle n+1 probleminin ne olduğunu bilmeyenler için şu yazıyı okuyabilirsiniz.

Şirketteki birkaç projemizde de kullanabilmek amacıyla n+1 db hit problemlerini çözmeye yarayan bir python paketi hazırladım. Şöyleki bir rest-framework serializerı verildiğinde onun için select_related, prefetch_related ve only metodlarının doğru kullanımlarını oluşturuyor ve bu şekilde n+1 hit problemini düşünmek zorunda kalmıyorsunuz. İlgilenenler için projenin github adresi. Aynı zamanda pypi üzerinden de paylaşıldı böylece pip ile kurup deneyebilirsiniz. Daha detaylı bilgi github’da mevcut. Geri dönüşünüz benim için çok değerli ilgilenir ve incelemek isterseniz issue veya pr açarak katkıda bulunabilirsiniz. Teşekkürler.

3 Beğeni

Elinize sağlık hocam. Önemli bir konuyu öğrenmiş olduk. Kodunuzu tam incelemedim ama kullanınca geri dönüşleri yazacağım inşallah. Bu konudan sonra biraz daha araştırma yapınca olası n+1 problemli sorguları tespit etmek için başka araçlar da geliştirilmiş olduğunu gördüm. İzninizle paylaşmak isterim burada.

Birincisi, sorgulama yapılan bir sayfada kaç adet SQL sorgusu yapıldığını, bunlardan kaç tanesi benzer kaç tanesi aynı sorgu gibi bilgileri veren django-debug-toolbar aracı. Pip yardımı ile yükledikten sonra ve gerekli ayarlamaları yaptıktan sonra DEBUG modu açıksa, yani True ise, sayfalarınızda sağ tarafta bir panel göreceksiniz, bu panel sorguyla ilgili bilgileri görmenizi sağlar.

İkincisi, sizin yaptığınız gibi bu soruna çözüm olarak geliştirilen bir araç var. Otomatik tespit ediyor ama mudahale yok. Sadece potansiyel n+1 problemlerini tespit ediyor.

1 Beğeni

Teşekkürler hocam Django Debug Toolbar’ı benim projede de kullandım zaten testler kısmında çok faydalı bir araç. Geliştirme sürecinde çok faydası oluyor öneriyorum herkese. N+1 probleminden haberi olmayan çok kişi olduğunu fark ettim ben de. Bu django ve django-rest-framework’ün dokümantasyonlarındaki eksiklikten kaynaklanıyor bence. select_related ve prefetch_related’den bahsediyor django ama neden kullanılması gerektiğine dair çok iyi bir açıklaması yok.

Bu problem ise öyle halının altına süpürebileceğimiz cinsten değil. Çok ciddi performans kayıplarına yol açıyor. Örneğin benim örnek projemde çok çok ufak bir veritabanı üzerinde(1mb’den küçük) 2 ya da 3 seviye nested olarak kullanılan bir modeli json olarak döndüren bir view N+1 ile bir dakika sürüyor sonuç dönmesi ki bazen benim local makinem çöküyor. N+1’i çözdüğümde ise 1-2 saniye içerisinde sonuç dönüyor. Daha büyük bir veritabanında ya da daha nested modelleri kullandığımızda fark çok daha dramatik olabilir. (Nested modeller ilişkileri sebebiyle daha da fazla db hitine yol açıyorlar)

1 Beğeni