İndeksler
Güçlü indeks stratejileriyle sorgu performansını optimize edin
İndeksler
İndeksler, Isar'ın sorgu optimizasyonundaki en güçlü özelliğidir. Tekil, bileşik ve çok girişli indeksleri etkin biçimde kullanmayı öğrenin.
İndeksleri anlamak, sorgu performansını optimize etmenin anahtarıdır!
İndeks Nedir?
İndeks olmadan sorgular her nesneyi tek tek taramak zorundadır. İndekslerle sorgular doğrudan ilgili verilere atlayabilir.
İndekssiz Örnek
@collection
class Product {
Id? id;
late String name;
late int price;
}İndekssiz Veri:
| id | name | price |
|---|---|---|
| 1 | Book | 15 |
| 2 | Table | 55 |
| 3 | Chair | 25 |
| 4 | Pencil | 3 |
| 5 | Lightbulb | 12 |
| 6 | Carpet | 60 |
| 7 | Pillow | 30 |
| 8 | Computer | 650 |
| 9 | Soap | 2 |
€30'dan büyük ürünleri bulmak için Isar 9 satırın tamamını kontrol eder:
final expensive = await isar.products.where()
.priceGreaterThan(30)
.findAll();İndeksli
price alanına indeks ekleyin:
@collection
class Product {
Id? id;
late String name;
@Index()
late int price;
}Oluşan İndeks (sıralı):
| price | id |
|---|---|
| 2 | 9 |
| 3 | 4 |
| 12 | 5 |
| 15 | 1 |
| 25 | 3 |
| 30 | 7 |
| 55 | 2 |
| 60 | 6 |
| 650 | 8 |
Artık sorgu doğrudan ilgili satırlara atlar! ⚡
İndeks Oluşturma
Tek Alan İndeksi
@collection
class User {
Id? id;
@Index()
late String email;
@Index(type: IndexType.value)
late String username;
}Varsayılan - Değerin kendisini saklar. Tüm where cümlelerini destekler.
@Index(type: IndexType.value)
late String email;
// Destekler: equalTo, between, startsWith vb.
await isar.users.where()
.emailStartsWith('john')
.findAll();Değerin hash'ini saklar. Yalnızca eşitlik kontrollerini destekler. Daha az yer kaplar.
@Index(type: IndexType.hash)
late String email;
// Yalnızca: equalTo
await isar.users.where()
.emailEqualTo('john@example.com')
.findAll();Sadece List'ler için. Her elemanı ayrı ayrı hash'ler.
@Index(type: IndexType.hashElements)
late List<String> tags;
await isar.posts.where()
.tagsElementEqualTo('flutter')
.findAll();Bileşik İndeksler
Karmaşık sorgular için birden fazla alanı birlikte indeksleyin:
@collection
class Person {
Id? id;
late String firstName;
@Index(composite: ['firstName'])
late String lastName;
late int age;
}// Bileşik indeksi verimli kullanır
final people = await isar.persons
.where()
.lastNameFirstNameEqualTo('Doe', 'John')
.findAll();Bileşik indeksler ilk alan tek başına kullanılarak da sorgulanabilir: .lastNameEqualTo('Doe')
Çok Alanlı Bileşik
@collection
@Index(composite: ['lastName', 'age'])
class Person {
Id? id;
late String firstName;
late String lastName;
late int age;
}// Aşağıdakilerin hepsi bileşik indeksi kullanır:
.firstNameEqualTo('John')
.firstNameLastNameEqualTo('John', 'Doe')
.firstNameLastNameAgeEqualTo('John', 'Doe', 25)Çok Girişli İndeksler
Liste elemanları için indeksler oluşturun:
@collection
class Post {
Id? id;
late String title;
@Index(type: IndexType.value)
late List<String> tags;
}// Herhangi bir tag'e göre hızlı arama
final flutterPosts = await isar.posts
.where()
.tagsElementEqualTo('flutter')
.findAll();Çok girişli indeksler, çok elemanlı listelerde veritabanı boyutunu ciddi şekilde artırabilir.
Benzersiz İndeksler
Benzersizlik koşulları uygulayın:
@collection
class User {
Id? id;
@Index(unique: true)
late String username;
late int age;
}await isar.writeAsync((isar) async {
final user1 = User()
..id = 1
..username = 'john_doe'
..age = 25;
await isar.users.put(user1); // ✅ eklendi
final user2 = User()
..id = 2
..username = 'john_doe'
..age = 30;
await isar.users.put(user2); // ✅ önceki kayıt sessizce silinir
final son = await isar.users
.where()
.usernameEqualTo('john_doe')
.findFirst();
print(son);
// {id: 2, username: john_doe, age: 30}
});v4 benzersiz indeksler overwrite eder
Aynı anahtar kombinasyonunu ikinci kez yazarsanız Isar, önceki kaydı silip yenisini yazar. Duplicate girişleri reddetmek istiyorsanız kendiniz kontrol ekleyin:
await isar.writeAsync((isar) async {
final varMi = await isar.users
.where()
.usernameEqualTo('john_doe')
.findFirst();
if (varMi != null) {
throw StateError('username zaten kullanılıyor');
}
final user = User()
..id = 42
..username = 'john_doe'
..age = 30;
await isar.users.put(user);
});Büyük/Küçük Harf Duyarlılığı
String indekslerinde harf duyarlılığını kontrol edin:
@collection
class User {
Id? id;
@Index(caseSensitive: false)
late String email;
}// Her ikisi de aynı kullanıcıyı bulur
await isar.users.where().emailEqualTo('JOHN@example.com').findAll();
await isar.users.where().emailEqualTo('john@example.com').findAll();Büyük/küçük harf duyarsız indeksler biraz daha fazla yer kaplar ama esnek sorgular sağlar.
Sıralama için İndeks
İndeksler süper hızlı sıralama sunar:
@collection
class Product {
Id? id;
late String name;
@Index()
late int price;
}// ❌ Yavaş - tüm kayıtları yükleyip sonra sıralar
final cheapest = await isar.products
.where()
.sortByPrice()
.limit(4)
.findAll();// ✅ Hızlı - sıralı indeksi kullanır
final cheapest = await isar.products
.where()
.anyPrice()
.limit(4)
.findAll();İndeksli sıralama, sonuçların tamamını belleğe yükleyip sıralama ihtiyacını ortadan kaldırır!
Where Cümleleri
Maksimum performans için where cümlelerinde indeksleri kullanın:
@collection
class Product {
Id? id;
late String name;
@Index()
late int price;
}// Hızlı - indeks kullanır
final products = await isar.products
.where()
.priceBetween(10, 100)
.findAll();
// Hızlı - indeks + sıralama
final sorted = await isar.products
.where()
.anyPrice()
.limit(10)
.findAll();
// Hızlı - indeks + filtre
final filtered = await isar.products
.where()
.priceGreaterThan(50)
.where()
.nameStartsWith('iPhone')
.findAll();İndeks Tipi Karşılaştırması
| Tip | Boyut | Where Cümleleri | Kullanım Alanı |
|---|---|---|---|
IndexType.value | Büyük | Hepsi | Tam metin arama, aralıklar |
IndexType.hash | Küçük | Sadece eşitlik | Benzersiz kısıt, lookup |
IndexType.hashElements | Orta | Liste elemanları | Etiket sistemleri, kategoriler |
En İyi Uygulamalar
Doğru Alanları Seçin
Where cümlelerinde sık kullanılan alanları indeksleyin:
@collection
class User {
Id? id;
@Index() // Sık sorgulanır
late String email;
late String name; // Nadiren tek başına sorgulandığı için indeks yok
}Aşırı İndeks Kullanmayın
Her indeks yazma süresini ve depolamayı artırır:
// ❌ Çok fazla indeks
@collection
class User {
@Index() Id? id; // Id zaten indekslenmiş!
@Index() late String email;
@Index() late String name;
@Index() late String phone;
@Index() late int age;
}
// ✅ Sadece sorguladığını indeksle
@collection
class User {
Id? id;
@Index(unique: true) late String email;
late String name;
late String phone;
late int age;
}Bileşik İndeksleri Doğru Kullanın
// ✅ İyi - firstName + lastName birlikte sorgulanıyor
@Index(composite: ['lastName'])
late String firstName;
// ❌ Kötü - ayrı ayrı sorgular
@Index()
late String firstName;
@Index()
late String lastName;Sorgularınızı Profilleyin
Isar Inspector ile sorgu performansını analiz edin:
// Debug modunda inspector'ı etkinleştir
final isar = Isar.open(
schemas: [UserSchema],
inspector: true, // Inspector'ı aç
);İndeks Sınırlamaları
- String'lerin yalnızca ilk 1024 baytı indekslenir
- Web'de bileşik indeksler en fazla 3 alan içerebilir
- İndeksler yazma sürelerini artırır
- Ek depolama alanı tüketir
Sonraki Adımlar
Son Güncelleme