Her veritabanında olduğu gibi, MongoDB’de de dizinler geliştirme sürecinin kritik bir parçasıdır. Dizinler olmadan veritabanınız büyüdükçe performans düşmeye devam eder. Doğru dizinlerle ise veriniz artsa bile erişim performansı en iyi seviyede kalır.
Bu yazıda, MongoDB içinde mevcut çeşitli dizin türlerini, en iyi deneyim için bazı ipuçlarını ve oluşturduğunuz dizinlerden gerçekten yararlandığınızdan emin olmanız için yönergeleri inceleyeceğiz. MongoDB’yi hâlâ öğreniyorsanız, Introduction to MongoDB kursuna göz atmanızı öneririm.
MongoDB Dizinleri Nerede Önemlidir ve Neden?
Dizinlerden söz ettiğimizde performanstan söz ediyoruz. Dizinler, bir sorguya uyup uymadığını görmek için koleksiyondaki her belgeye bakmak ile sorgumuza uyan daha spesifik bir belge grubuna bakmak arasındaki farktır. Koleksiyonumuz küçükse ve taranacak çok belge yoksa performans her iki durumda da iyi olabilir. Ancak bir koleksiyonda 100.000 belge varsa ve yalnızca 100’ü sorgumuza uyuyorsa, bu 100’e dayalı bir dizin yoksa 100.000 belgenin tamamını gözden geçirmek zaman alacaktır.
MongoDB’de çok sayıda dizin türü vardır:
Tek alan: Belge içindeki belirli bir alan üzerinde dizin. Varsayılan _id alanı dizini tek alanlı bir dizin olarak düşünülebilir.
Bileşik: Bir belgenin birden çok alanına dayalı dizin; burada sorguda ve dizinde alanların sırası önemlidir.
Çok anahtarlı (Multikey): Dizi (array) alanlarında kullanılan dizin.
Joker (Wildcard): Belgeler arasında adı biraz farklılık gösterebilen alanları destekleyen dizin. Bu dizin, diğer dizinler kadar iyi performans göstermez.
Coğrafi uzamsal: Enlem ve boylam koordinat verisi kullanan coğrafi sorguların performansını artıran dizin.
Karma (Hashed): Parçalama anahtarlarıyla (shard key) birlikte en iyi kullanılan dizin.
Çoğu zaman tek alanlı, bileşik veya çok anahtarlı dizinler kullanırsınız; ancak nihayetinde bu, uygulamanın, sorguların ve verinin türüne bağlıdır.
Dizinler, belgeleri getiren her türlü veritabanı etkileşiminde önemlidir. Bu, find veya findOne işlemleriyle belge getirmeyle sınırlı değildir. Belgeleri güncellerken ve silerken de veritabanının güncelleme veya silme işlemi öncesinde belgeleri bulmak için kullanacağı bir eşleştirme ölçütü kullanırsınız.
Bir dizinden yararlanabilecek tek alma operatörleri find ve findOne değildir. Toplama hattınızın ilk aşamasında $match operatörünü kullandığınızda, bir dizin işleri dramatik biçimde hızlandırır.
Başarı için MongoDB Dizinleme İpuçları ve Püf Noktaları
Rastgele dizinler oluşturmak, MongoDB’de hiç dizin kullanmamak kadar verimsiz olabilir. Bunun yerine, daha verimli bir uygulama oluşturmanıza yardımcı olacak birkaç husus vardır.
Bileşik dizinler için eşitlik, sıralama, aralık (ESR)
Bileşik bir dizin oluştururken kural, sorgunuzdaki her alanı nasıl kullanacağınızı belirlemek ve ESR en iyi uygulamasını izlemesini sağlamaktır.
ESR ne anlama gelir? Parçalara ayıralım:
Eşitlik: Gevşek değil, tam eşleşme yapılacak alanlar. Örneğin, sorgunuzda birinin tam adını eşlemek bir eşitlik aşamasıdır.
Sıralama: Artan ya da azalan düzende sıralama için kullanacağınız alanlar.
Aralık: Tam eşleşme olmayacak alanlar. Örneğin $lt veya $gt operatörünü kullanmak, belirli bir eşleşme yerine bir aralıktaki belgelere eşleşir.
Tüm bunların ne anlama geldiğini daha iyi görmek için şu sorguya bakın:
Bellek içi sıralamaları önlemek ve performanslı bir sorgu yürütümü için arama alanını daraltmak adına ESR kurallarını takip etmek isteriz.
Kapsanan (covered) sorgular
Genel olarak dizinleme, sorgu çalıştırılırken taranacak daha küçük bir belge alt kümesi oluşturur ve bunun sonucu olarak performansı artırır. Ancak uygulama performansınızı bir üst seviyeye çıkarmak istiyorsanız, kapsanan sorguları araştırmalısınız. Kapsanan bir sorguda, sonuçların tamamını doğrudan dizinden alırsınız; koleksiyonunuzdaki hiçbir belgeyi taramanız gerekmez.
Burada, uygulamanızda kapsanan sorguları mümkün kılabilecek ya da kılmayabilecek birkaç koşul vardır:
Eşleştirme ölçütü ve sıralama, dizininizin oluşturulduğu yapıyla tam olarak uyuşmalıdır.
Sonuç kümesinde talep ettiğiniz alanlar da dizinle örtüşmelidir.
Parçalama yapıyorsanız, parça anahtarı dizininizin bir parçası olmalıdır.
Projeksiyon içeren bu sorgu dizinimizi kullanacaktır, ancak kapsanan bir sorgu olmayacaktır. MongoDB’de _id alanı varsayılan olarak döndürülür ve bu örnekte _id alanı dizinimize eklenmemiştir. Dolayısıyla ya dizini ya da sorguyu değiştirebiliriz. Sorguyu değiştirme örneğinde şunu yapabiliriz:
Unutmayın, kapsanan bir sorgu kullanmak istiyorsanız, dizin geçerli olmalı ve talep edilen alanlar dizine dahil olmalıdır. Aksi hâlde yalnızca dizince yönetilen belgeleri bulursunuz; belgenin kendisi dizin içinde değildir.
Kapsanan bir sorgu kullanılıp kullanılmadığını, bu makalenin ilerleyen kısmında bahsedilen explain operatöründeki executionStats argümanından yararlanarak doğrulayabilirsiniz. totalDocsExamined sonucundaki değer bunu belirler. Değer sıfırsa kapsanan bir sorgu kullanıyorsunuz demektir.
Gereksiz dizinleri azaltma veya ortadan kaldırma
Dizinler, sunucu kaynakları bağlamında ücretsiz değildir. Her dizin sunucu tarafından korunmalı ve bu bakım CPU, RAM ve disk kullanır. Daha fazla dizin oluşturdukça daha fazla ek yük yaratırsınız; bu da kaynakları yetersiz sağlanmış bir sunucu senaryosunda daha yüksek maliyetlere veya daha düşük performansa yol açabilir. Bu performans düşüşü yalnızca okumaları değil, MongoDB daha fazla kaynak tükettiği için yazma ve silmeleri de etkileyebilir.
Yalnızca yüksek frekansta çalıştırılan sorgular için dizinler oluşturmak iyi bir fikirdir. Ayda bir kez çalıştırılan o sorgunun gerçekten bir dizine ihtiyacı var mı? Muhtemelen hayır. Her 10 saniyede bir çalıştırılan o sorgunun bir dizine ihtiyacı var mı? Kesinlikle!
MongoDB içinde bir dizin oluşturmuş olmanız, çalıştırdığınız sorgunun onu gerçekten kullandığı anlamına gelmez. MongoDB’de, belirli bir sorgu için hangi dizinin kullanıldığını analiz edebiliriz.
Bu sorgu, geçerli bir dizin olsun ya da olmasın çalışacaktır ve veri kümesi küçükse her hâlükârda hızlı çalışır. Ancak dizini kullanıp kullanmadığını görmek istersek sorguya küçük bir ek yapabiliriz:
Bu kez yürütme planı "IXSCAN" kullandığımızı ve kullanılan dizinin adını belirtti; bu örnekte name_1_is_active_1. Dizin adını oluştururken otomatik olarak belirlenmişti.
update işlemi için süreç benzerdir; tek fark explain fonksiyonunun konumudur.
Yukarıdaki örnekte explain’in update fonksiyonundan önce geldiğine dikkat edin.
Güncelleme işleminizde beklenen dizini kullanıyorsanız, "IXSCAN" değeriyle birlikte dizin adını görürsünüz. Güncelleme işlemleri ve onlarla dizin kullanımı hakkında daha fazla bilgi edinin.
Sorgunuzun yürütme planı ayrıntılarını bulmanın alternatif bir yolu da veritabanında runCommand kullanmaktır. Görünüm olarak o kadar zarif olmasa da oldukça güçlüdür ve şöyle görünür:
Yukarıdaki işlem, explain fonksiyonlu güncelleme işlemiyle aynı şekilde çalışır.
Dizin oluşturmada kendinizi yeterli hissetmiyorsanız veya sorgularınızın beklenenden yavaş çalıştığını fark ediyorsanız, yürütme ayrıntılarını kontrol etmeyi düşünün.
Sonuç
MongoDB’de dizinleme ile ilgili bazı en iyi uygulamaları gördünüz. Her olası dizinleme senaryosunu ele almadık; ancak bunu, kullanıcılarınızın verilerinizle çalışırken mümkün olan en iyi deneyimi almasını sağlamaya yönelik bir başlangıç noktası olarak kullanabilirsiniz.
Birkaç noktayı yineleyelim:
Mümkün olduğunda eşitlik, sıralama, aralık (ESR) kuralını izleyin.
Yapabiliyorsanız kapsanan bir sorgu kullanmayı deneyin.
Dizin oluşturma konusunda aşırıya kaçmayın; bunun yerine en çok hangi sorguların kullanılacağını ve ne kadar veri getirildiğini belirleyin.
Dizinlerinizi ve performanslarını test etmek için explain operatöründen yararlanın.
Yukarıdaki maddeler, uygulama performansınızı artıracak dizinleme en iyi uygulamalarının kapsamlı bir listesi değildir. Kardinalite miktarları gibi başka etkenler de vardır.
Dizinleme konusunda daha fazla yardım için MongoDB dokümantasyonuna göz atın. MongoDB Atlas’ta ücretli bir katman kullanıyorsanız, dizin ve sorgu önerileri için yerleşik performans danışmanı araçlarını kullanmayı düşünün.
MongoDB Dizinleme SSS
Bir MongoDB koleksiyonunda kaç tane dizin oluşturmalıyım?⌄
Duruma bağlıdır. Size uygun dengeyi bulmanız gerekir; ancak ara sıra yerine sıkça çalıştırılan sorgular için dizinlemeyi düşünün.
Birkaç dizin oluşturdum ama sorgularım hâlâ yavaş. Neden?⌄
Oluşturduğunuz dizinleri sorgularınızın gerçekten kullandığından emin misiniz? Sorun gidermek için explain operatöründen veya MongoDB Atlas’taki danışman araçlarından yararlanın.
ESR kuralı için dizin alan sırası mutlaka eşitlik, sonra sıralama, sonra aralık şeklinde mi olmalı?⌄
MongoDB bazen bir dizini sıra dışı da kullanabilir; ancak en etkilisi, dizin anahtar sırasının önce eşitlik filtreleri, sonra sıralamalar ve son olarak aralık olacak şekilde sorgunun sırasıyla eşleşmesidir.
Farklı explain modları nelerdir? ⌄
Varsayılan olarak explain() “queryPlanner” modunda çalışır; ancak farklı modlar da vardır: “executionStats” ve “allPlansExecution”.
Yazar
Nic Raboy
Nic Raboy , MongoDB'de Geliştirici İlişkileri Lideridir ve MongoDB'yi projelerine dahil etmelerinde geliştiricilerin başarılı olmasına yardımcı olacak harika içerikler üreten Python, Java, C# ve PHP geliştiricilerinden oluşan bir ekibi yönetir. Golang ve JavaScript konusunda deneyime sahiptir ve sık sık geliştirme maceraları hakkında yazılar yazar.
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Her veritabanında olduğu gibi, MongoDB’de de dizinler geliştirme sürecinin kritik bir parçasıdır. Dizinler olmadan veritabanınız büyüdükçe performans düşmeye devam eder. Doğru dizinlerle ise veriniz artsa bile erişim performansı en iyi seviyede kalır.
Bu yazıda, MongoDB içinde mevcut çeşitli dizin türlerini, en iyi deneyim için bazı ipuçlarını ve oluşturduğunuz dizinlerden gerçekten yararlandığınızdan emin olmanız için yönergeleri inceleyeceğiz. MongoDB’yi hâlâ öğreniyorsanız, Introduction to MongoDB kursuna göz atmanızı öneririm.
MongoDB Dizinleri Nerede Önemlidir ve Neden?
Dizinlerden söz ettiğimizde performanstan söz ediyoruz. Dizinler, bir sorguya uyup uymadığını görmek için koleksiyondaki her belgeye bakmak ile sorgumuza uyan daha spesifik bir belge grubuna bakmak arasındaki farktır. Koleksiyonumuz küçükse ve taranacak çok belge yoksa performans her iki durumda da iyi olabilir. Ancak bir koleksiyonda 100.000 belge varsa ve yalnızca 100’ü sorgumuza uyuyorsa, bu 100’e dayalı bir dizin yoksa 100.000 belgenin tamamını gözden geçirmek zaman alacaktır.
MongoDB’de çok sayıda dizin türü vardır:
_idalanı dizini tek alanlı bir dizin olarak düşünülebilir.Çeşitli dizin türleri hakkında daha fazla bilgi için MongoDB dokümantasyonuna bakın.
Çoğu zaman tek alanlı, bileşik veya çok anahtarlı dizinler kullanırsınız; ancak nihayetinde bu, uygulamanın, sorguların ve verinin türüne bağlıdır.
Dizinler, belgeleri getiren her türlü veritabanı etkileşiminde önemlidir. Bu,
findveyafindOneişlemleriyle belge getirmeyle sınırlı değildir. Belgeleri güncellerken ve silerken de veritabanının güncelleme veya silme işlemi öncesinde belgeleri bulmak için kullanacağı bir eşleştirme ölçütü kullanırsınız.Bir dizinden yararlanabilecek tek alma operatörleri
findvefindOnedeğildir. Toplama hattınızın ilk aşamasında$matchoperatörünü kullandığınızda, bir dizin işleri dramatik biçimde hızlandırır.Başarı için MongoDB Dizinleme İpuçları ve Püf Noktaları
Rastgele dizinler oluşturmak, MongoDB’de hiç dizin kullanmamak kadar verimsiz olabilir. Bunun yerine, daha verimli bir uygulama oluşturmanıza yardımcı olacak birkaç husus vardır.
Bileşik dizinler için eşitlik, sıralama, aralık (ESR)
Bileşik bir dizin oluştururken kural, sorgunuzdaki her alanı nasıl kullanacağınızı belirlemek ve ESR en iyi uygulamasını izlemesini sağlamaktır.
ESR ne anlama gelir? Parçalara ayıralım:
$ltveya$gtoperatörünü kullanmak, belirli bir eşleşme yerine bir aralıktaki belgelere eşleşir.Tüm bunların ne anlama geldiğini daha iyi görmek için şu sorguya bakın:
Yukarıdaki sorgu bölümde eşitlik eşleşmesi, maaşta aralık eşleşmesi yapar ve sonuçları ada göre sıralar.
ESR kurallarını izlediğimizde dizin şöyle görünür:
Bellek içi sıralamaları önlemek ve performanslı bir sorgu yürütümü için arama alanını daraltmak adına ESR kurallarını takip etmek isteriz.
Kapsanan (covered) sorgular
Genel olarak dizinleme, sorgu çalıştırılırken taranacak daha küçük bir belge alt kümesi oluşturur ve bunun sonucu olarak performansı artırır. Ancak uygulama performansınızı bir üst seviyeye çıkarmak istiyorsanız, kapsanan sorguları araştırmalısınız. Kapsanan bir sorguda, sonuçların tamamını doğrudan dizinden alırsınız; koleksiyonunuzdaki hiçbir belgeyi taramanız gerekmez.
Burada, uygulamanızda kapsanan sorguları mümkün kılabilecek ya da kılmayabilecek birkaç koşul vardır:
Peki tüm bunlar ne anlama geliyor?
Örneğin, aşağıdaki dizine bakalım:
Yukarıdaki örnekte belgelerimizin
countryvesalaryalanlarına göre dizinlenmesini istiyoruz. Sonra şu sorguyu çalıştırabiliriz:Projeksiyon içeren bu sorgu dizinimizi kullanacaktır, ancak kapsanan bir sorgu olmayacaktır. MongoDB’de
_idalanı varsayılan olarak döndürülür ve bu örnekte_idalanı dizinimize eklenmemiştir. Dolayısıyla ya dizini ya da sorguyu değiştirebiliriz. Sorguyu değiştirme örneğinde şunu yapabiliriz:Unutmayın, kapsanan bir sorgu kullanmak istiyorsanız, dizin geçerli olmalı ve talep edilen alanlar dizine dahil olmalıdır. Aksi hâlde yalnızca dizince yönetilen belgeleri bulursunuz; belgenin kendisi dizin içinde değildir.
Kapsanan bir sorgu kullanılıp kullanılmadığını, bu makalenin ilerleyen kısmında bahsedilen
explainoperatöründekiexecutionStatsargümanından yararlanarak doğrulayabilirsiniz.totalDocsExaminedsonucundaki değer bunu belirler. Değer sıfırsa kapsanan bir sorgu kullanıyorsunuz demektir.Gereksiz dizinleri azaltma veya ortadan kaldırma
Dizinler, sunucu kaynakları bağlamında ücretsiz değildir. Her dizin sunucu tarafından korunmalı ve bu bakım CPU, RAM ve disk kullanır. Daha fazla dizin oluşturdukça daha fazla ek yük yaratırsınız; bu da kaynakları yetersiz sağlanmış bir sunucu senaryosunda daha yüksek maliyetlere veya daha düşük performansa yol açabilir. Bu performans düşüşü yalnızca okumaları değil, MongoDB daha fazla kaynak tükettiği için yazma ve silmeleri de etkileyebilir.
Yalnızca yüksek frekansta çalıştırılan sorgular için dizinler oluşturmak iyi bir fikirdir. Ayda bir kez çalıştırılan o sorgunun gerçekten bir dizine ihtiyacı var mı? Muhtemelen hayır. Her 10 saniyede bir çalıştırılan o sorgunun bir dizine ihtiyacı var mı? Kesinlikle!
Birkaç dizinleme en iyi uygulamasını MongoDB Blog’da öğrenin.
MongoDB Dininiz Çalışıyor mu?
MongoDB içinde bir dizin oluşturmuş olmanız, çalıştırdığınız sorgunun onu gerçekten kullandığı anlamına gelmez. MongoDB’de, belirli bir sorgu için hangi dizinin kullanıldığını analiz edebiliriz.
Örneğin, şu dizine bakalım:
Yukarıdaki örnekte
nameveis_activealanlarını dizinliyoruz. Şimdi şu sorguyu çalıştırmak istiyoruz:Bu sorgu, geçerli bir dizin olsun ya da olmasın çalışacaktır ve veri kümesi küçükse her hâlükârda hızlı çalışır. Ancak dizini kullanıp kullanmadığını görmek istersek sorguya küçük bir ek yapabiliriz:
Bu kez sorgunun yürütme planını almak için
explainmetodunu kullanıyoruz. Yürütme planında şunu görebiliriz:Bu sorgu için MongoDB "COLLSCAN" kullandı; yani alanlarımızdan birini içerse de dizinimizi kullanmadı. Sorguyu şöyle değiştirirsek:
explainsonucumuz değişti:Bu kez yürütme planı "IXSCAN" kullandığımızı ve kullanılan dizinin adını belirtti; bu örnekte
name_1_is_active_1. Dizin adını oluştururken otomatik olarak belirlenmişti.updateişlemi için süreç benzerdir; tek farkexplainfonksiyonunun konumudur.updateişlemi şu şekilde görünebilir:Yukarıdaki örnekte
explain’inupdatefonksiyonundan önce geldiğine dikkat edin.Güncelleme işleminizde beklenen dizini kullanıyorsanız, "IXSCAN" değeriyle birlikte dizin adını görürsünüz. Güncelleme işlemleri ve onlarla dizin kullanımı hakkında daha fazla bilgi edinin.
Sorgunuzun yürütme planı ayrıntılarını bulmanın alternatif bir yolu da veritabanında
runCommandkullanmaktır. Görünüm olarak o kadar zarif olmasa da oldukça güçlüdür ve şöyle görünür:Yukarıdaki işlem,
explainfonksiyonlu güncelleme işlemiyle aynı şekilde çalışır.Dizin oluşturmada kendinizi yeterli hissetmiyorsanız veya sorgularınızın beklenenden yavaş çalıştığını fark ediyorsanız, yürütme ayrıntılarını kontrol etmeyi düşünün.
Sonuç
MongoDB’de dizinleme ile ilgili bazı en iyi uygulamaları gördünüz. Her olası dizinleme senaryosunu ele almadık; ancak bunu, kullanıcılarınızın verilerinizle çalışırken mümkün olan en iyi deneyimi almasını sağlamaya yönelik bir başlangıç noktası olarak kullanabilirsiniz.
Birkaç noktayı yineleyelim:
explainoperatöründen yararlanın.Yukarıdaki maddeler, uygulama performansınızı artıracak dizinleme en iyi uygulamalarının kapsamlı bir listesi değildir. Kardinalite miktarları gibi başka etkenler de vardır.
Dizinleme konusunda daha fazla yardım için MongoDB dokümantasyonuna göz atın. MongoDB Atlas’ta ücretli bir katman kullanıyorsanız, dizin ve sorgu önerileri için yerleşik performans danışmanı araçlarını kullanmayı düşünün.