MongoDB'de indeks yönü neden önemli?


114

Alıntı docs :

Bir dizin oluştururken, bir anahtarla ilişkili sayı dizinin yönünü belirtir, bu nedenle her zaman 1 (artan) veya -1 (azalan) olmalıdır. Yön, tek anahtar dizinler veya rastgele erişim alımı için önemli değildir, ancak bileşik dizinler üzerinde sıralama veya aralık sorguları yapıyorsanız önemlidir.

Ancak, bileşik endekslerde endeksin yönünün önemli olması için hiçbir neden göremiyorum. Birisi lütfen daha fazla açıklama (veya bir örnek) sağlayabilir mi?

Yanıtlar:


113

MongoDB, bileşik anahtarı bir şekilde birleştirir ve bir BTree'de anahtar olarak kullanır.

Tek öğeleri bulurken - Ağaçtaki düğümlerin sırası önemsizdir.

Bir dizi düğüm döndürüyorsanız - Birbirine yakın öğeler ağacın aynı dallarında olacaktır. Düğümler aralık içinde ne kadar yakınsa, o kadar çabuk geri alınabilirler.

Tek alan dizini ile - Sıranın önemi yoktur. Artan sırada birbirlerine yakınlarsa, azalan sırada da birbirlerine yakın olurlar.

Bileşik anahtarınız olduğunda - Sıra önemli olmaya başlar.

Örneğin, anahtar yükselen A B ise, dizin şuna benzer şekilde görünebilir:

AB Satırı
1 1 1
2 2 6
3 2 7 
4 3 4
5 3 5
6 3 6
7 5 1

Artan B'ye yönelik bir sorgunun, satırları döndürmek için dizinin dışına sırayla atlaması gerekecek ve daha yavaş olacaktır. Örneğin, Satır döndürür1, 3, 2, 6, 5, 4, 7

Dizinle aynı sıradaki aralıklı bir sorgu, satırları sırayla doğru sırayla döndürür.

Bir BTree'de kayıt bulmak O (Log (n)) süresi alır. Sırayla bir dizi kayıt bulmak yalnızca OLog (n) + k şeklindedir; burada k, döndürülecek kayıt sayısıdır.

Kayıtlar bozuksa, maliyet OLog (n) * k kadar yüksek olabilir.


1
Ortaya çıkan satır muhtemelen 1, 3, 2, 6, 5, 4, 7?
johndodo

Hala daha yavaş olması için bir neden göremiyorum. Yalnızca algoritma farklı olmalıdır (A'daki her değer grubu için grubun sonuna atlamalı ve ters sırada işlemelidir), ancak MongoDB dizinleri hafızada olduğundan hız üzerinde fark edilebilir bir etkisi olmamalıdır. Ayrıca, RDBMS dizinlerle yön hakkında hiçbir şey bilmiyor ve oradaki durum oldukça benzer afaik mi?
johndodo

8
Bunun bir performans vuruşu olmasının nedeni, basitleştirilmiş örnek gibi bellekte sıralı bir liste olmamasıdır. Aslında ağırlıklı bir ağaç. Sıradan atlama, ağacın tekrar üzerinden geçilmesini gerektirecektir. RDMS kesinlikle indeksleme düzenine sahiptir.
Jared Kells

1
Bir BTree'den düğümleri sırayla getirmek, her yaprak boyunca siz bitene kadar hareket etmek ve ardından bir seviye yukarı ve bir sonraki dalda aşağı gitmek kadar basittir. O (n) Arızalı çok daha fazla CPU yoğun.
Jared Kells

Daha fazla açıklama için teşekkürler. Belgeleri MySQL dizinleri için kontrol ettim - dizin yönünü belirtmek gerçekten mümkün, ancak ayar yok sayılıyor.
johndodo

46

En basit cevap aradığınız o yönde olmasıdır İki veya daha fazla alanlarda sıralama zaman Önemli olan .

Sıralama yapıyorsanız {a : 1, b : -1}:

Dizin {a : 1, b : 1}, dizinden daha yavaş olacaktır{a : 1, b : -1}


1
@MarkPieszak çünkü tüm sıralama hafızada yapılmalı ve dizini işe yaramaz hale
getirecek

@Sammaye Bence bu doğru fikir, ancak tüm türden olup olmadığından emin değilim . Ben gerçekten nasıl çalıştığını bilmek uygulamaya bakmak gerekirdi, ama ben sonuçları ile geri çekti sıralanabilir düşünürdüm bir yalnız ve sonra ek b sıralama hafızasında yapılması gerekir.
Zaid Masud

1
hmm, en son kodu kontrol ettiğimde, sıralamanın nasıl olduğuna bağlı olarak kısmi sıralamaları düşürmesi tuhaf, ama belki değişmiştir
Sammaye

Ya sıralıyorsam, indeksim {a: -1, b: -1}olmalı mı {a: -1, b: -1}yoksa {a: 1, b: 1}yeterli olacaktır.
Hussain

@Hussain örneğinizde, {a: 1, b: 1}bir dizini tamamen tersine çevirmek iyi olduğu için dizin yeterli olmalıdır. ör. Dizin açık {a: 1}bir sıralama için kullanılabilir{a: -1}
Zaid Masud

12

Neden dizinler

İki önemli noktayı anlayın.

  1. Bir indeks indeks olmamasından daha iyi olsa da, doğru indeks her ikisinden de çok daha iyidir.
  2. MongoDB, sorgu başına yalnızca bir dizin kullanacak ve muhtemelen kullanmak istediğinizi uygun alan sıralamasıyla bileşik dizinler oluşturacaktır.

Dizinler ücretsiz değildir. Hafızayı alırlar ve ekleme, güncelleme ve silme işlemleri yaparken performans cezası verirler. Normalde performans isabeti ihmal edilebilir düzeydedir (özellikle okuma performansındaki kazançlarla karşılaştırıldığında), ancak bu, dizinlerimizi oluşturma konusunda akıllı olamayacağımız anlamına gelmez.

Nasıl Dizinler

Hangi alan grubunun birlikte dizine eklenmesi gerektiğini belirlemek, çalıştırmakta olduğunuz sorguları anlamakla ilgilidir. Dizininizi oluşturmak için kullanılan alanların sırası kritiktir. İyi haber şu ki, sırayı yanlış anlarsanız, endeks hiç kullanılmayacak, bu yüzden açıklamayla fark edilmesi kolay olacak.

Neden Sıralama

Sorgularınızın Sıralama gerektirebilir. Ancak sıralama pahalı bir işlem olabilir, bu nedenle sıraladığınız alanları tıpkı sorguladığınız bir alan gibi ele almak önemlidir. Yani indeksi varsa daha hızlı olacaktır. Yine de önemli bir fark vardır, sıraladığınız alan dizininizdeki son alan olmalıdır. Bu kuralın tek istisnası, alanın da sorgunuzun bir parçası olması durumunda, son olması gereken kuralın uygulanmamasıdır.

Nasıl Sıralama

Dizinin tüm anahtarlarında veya bir alt kümede bir sıralama belirtebilirsiniz; ancak, sıralama anahtarları dizinde göründükleri sırayla listelenmelidir. Örneğin, bir dizin anahtarı kalıbı {a: 1, b: 1}, {a: 1, b: 1} 'de sıralamayı destekleyebilir ancak {b: 1, a: 1}' de desteklemez.

Sıralama, tüm anahtarları için indeks anahtarı modeli olarak aynı sıralama yönünü (yani artan / azalan) belirtmeli veya indeks anahtarı modeli olarak tüm anahtarları için ters sıralama yönünü belirtmelidir. Örneğin, bir dizin anahtarı kalıbı {a: 1, b: 1}, {a: 1, b: 1} ve {a: -1, b: -1} 'de sıralamayı destekleyebilir ancak {a: -1'de desteklemez , b: 1}.

Şu dizinlerin olduğunu varsayalım:

{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }

Example                                                    Index Used
db.data.find().sort( { a: 1 } )                            { a: 1 }
db.data.find().sort( { a: -1 } )                           { a: 1 }
db.data.find().sort( { a: 1, b: 1 } )                      { a: 1, b: 1 }
db.data.find().sort( { a: -1, b: -1 } )                    { a: 1, b: 1 }
db.data.find().sort( { a: 1, b: 1, c: 1 } )                { a: 1, b: 1, c: 1 }
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )   { a: 1, b: 1 }

Bunun bir örnek olduğunu anlıyorum ama eğer indeks { a: 1, b: 1, c: 1 }varsa gerçekten indekslere ihtiyacınız var mı { a: 1}ve / { a: 1, b: 1}veya indeks { a: 1, b: 1, c: 1 }tüm vakaları kapsar mı? Sorgular her zaman aynı sıralamayı kullanıyorsa: -1 ile sorguda 1 sıralama yok
Lukas Liesis

1
Yalnızca 'a' özelliği üzerinde çalışan birçok sorgu varsa, veritabanı motoru için 'a' özelliğine sahip dizin ile arama yapmak, 'a', 'b', 'c' 3 özellikli dizine göre aramaya göre daha hızlıdır. Çünkü indeks boyutu artacak ve sayımı da artacaktır. ex. Kitapta 20 bölüm varsa. Bu nedenle 3. bölüme ve ardından belirli sayfaya gitmek daha hızlıdır. @LukasLiesis
Somnath Muluk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.