Android, Android'de kullanıma sunulan SQLite için yerleşik destek daha verimli bir SQL veritabanıdır. Uygulamanızın performansını optimize etmek için Böylece, verileriniz büyüdükçe verilerinizin hızlı ve öngörülebilir hızda kalmasını sağlar. Bu en iyi uygulamaları kullanarak, yeniden oluşturması ve sorunlarını gidermesi zor olan performans sorunlarınla karşılaşma olasılığını da azaltırsınız.
Daha hızlı performans elde etmek için aşağıdaki performans ilkelerini uygulayın:
Daha az satır ve sütun okuma: Sorgularınızı yalnızca işleyeceğiz. Veri tabanından okunan veri miktarını en aza indirin çünkü performansı etkileyebilir.
Çalışmayı SQLite Engine'e aktarın: Hesaplama, filtreleme ve sıralama işlemleri gerçekleştirin işlemleri gerçekleştirmelerini sağlar. SQLite'ın sorgu motorunu kullanarak performansı artırır.
Veritabanı şemasını değiştirme: Veritabanı şemanızı, SQLite'in etkili sorgu planları ve veri temsilleri oluşturmasına yardımcı olacak şekilde tasarlayın. Tabloları uygun şekilde dizine ekleme ve performansı artırmak için tablo yapılarını optimize edin.
Ayrıca, sorun giderme araçlarını kullanarak gereken alanları belirlemenize yardımcı olması için SQLite veritabanınızın optimize edebilirsiniz.
Jetpack Room kitaplığını kullanmanızı öneririz.
Veritabanını performans için yapılandırma
Veritabanınızı optimum şekilde yapılandırmak için bu bölümdeki adımları uygulayın. performansı hakkında daha fazla bilgi edinin.
Yazma Öncesi Günlük Kaydını Etkinleştir
SQLite, mutasyonları zaman zaman bir günlüğe ekleyerek uygular. veritabanına sıkıştırılır. Buna Write-Ahead Logging (Yazma Öncesi Günlük Kaydı) adı verilir. (WAL) ile değiştirin.
Etkinleştir
DUVAR
(ATTACH
DATABASE
kullanmıyorsanız)
Senkronizasyon modunu gevşetin
WAL kullanırken, her kaydetme işlemi için varsayılan olarak bir fsync
verilir. Bu sayede
verinin diske ulaşması anlamına gelir. Bu işlem, verilerin dayanıklılığını artırır ancak
kaydeder.
SQLite'te senkron modunu kontrol etme seçeneği vardır. Şu durumda:
WAL'yi etkinleştir, eşzamanlı modu NORMAL
olarak ayarla:
Kotlin
db.execSQL("PRAGMA synchronous = NORMAL")
Java
db.execSQL("PRAGMA synchronous = NORMAL");
Bu ayarda, bir kaydetme işlemi, veriler diskte depolanmadan önce dönebilir. güç kesintisi veya çekirdek paniği gibi durumlarda cihazın kapanması kaydedilen veriler kaybolabilir. Ancak, günlük kaydı nedeniyle veritabanınız bozuk.
Yalnızca uygulamanız kilitlenirse verileriniz diske erişmeye devam eder. Çoğu uygulamada bu ayar, ayarı, herhangi bir maliyet olmadan performans iyileştirmeleri sağlar.
Verimli tablo şemaları tanımlama
Performansı optimize etmek ve veri tüketimini en aza indirmek için verimli bir tablo şemasına bakalım. SQLite, verimli sorgu planları ve veriler oluşturur. Bu sayede, verileri daha hızlı almanıza yardımcı olur. Bu bölümde, tablo şemaları oluşturmayla ilgili en iyi uygulamalar yer almaktadır.
INTEGER PRIMARY KEY
ürününü düşünün
Bu örnekte, bir tabloyu aşağıdaki gibi tanımlayıp doldurun:
CREATE TABLE Customers(
id INTEGER,
name TEXT,
city TEXT
);
INSERT INTO Customers Values(456, 'John Lennon', 'Liverpool, England');
INSERT INTO Customers Values(123, 'Michael Jackson', 'Gary, IN');
INSERT INTO Customers Values(789, 'Dolly Parton', 'Sevier County, TN');
Tablo çıktısı aşağıdaki gibidir:
satır kimliği | id | ad | şehir |
---|---|---|---|
1 | 456 | Can Lennon | Liverpool, İngiltere |
2 | 123 | Michael Jackson | Gary, Indiana |
3 | 789 | Dolly Parton | Sevier County, TN |
rowid
sütunu
ekleme talimatını koruyan bir dizin. Sorguların
rowid
filtresi, hızlı bir B ağacı araması olarak uygulanır, ancak
id
filtresi yavaş bir tablo taramadır.
id
tarihine kadar arama yapmayı planlıyorsanız,
Depolama alanında daha az veri, toplamda ise daha az veri için rowid
sütunu
daha hızlı veritabanı:
CREATE TABLE Customers(
id INTEGER PRIMARY KEY,
name TEXT,
city TEXT
);
Tablonuz artık aşağıdaki gibi görünür:
id | ad | şehir |
---|---|---|
123 | Michael Jackson | Gary, Indiana |
456 | Can Lennon | Liverpool, İngiltere |
789 | Dolly Parton | Sevier County, TN |
rowid
sütununu depolamanız gerekmediğinden, id
sorguları hızlıdır. Not
Böylece, tablonun artık kampanya siparişi yerine id
temel alınarak sıralandığı gösteriliyor.
Dizinleri kullanarak sorguları hızlandırma
SQLite, sorguları hızlandırmak için dizinler kullanır. Filtreleme sırasında (WHERE
), sıralama yaparken (ORDER BY
) veya
bir sütun toplanıyorsa (GROUP BY
), tablonun sütun için bir dizini varsa
sorgu hızlandırıldı.
Yukarıdaki örnekte, city
ölçütüne göre filtreleme yapmak için tablonun tamamının taranması gerekir:
SELECT id, name
WHERE city = 'London, England';
Çok sayıda şehir sorgusu olan bir uygulamada, bu sorguları bir dizinle hızlandırabilirsiniz:
CREATE INDEX city_index ON Customers(city);
Bir dizin, ek bir tablo olarak uygulanır. Bu dizin, dizin sütununa göre sıralanır ve
rowid
ile eşlendi:
şehir | satır kimliği |
---|---|
Gary, Indiana | 2 |
Liverpool, İngiltere | 1 |
Sevier County, TN | 3 |
city
sütunu artık hem orijinal tabloda hem de dizinde bulunduğundan, sütunun depolama maliyetinin iki katına çıktığını unutmayın.
ek depolama alanı maliyeti, daha hızlı sorguların yararınadır.
Ancak, ödeme yaparken kullanmadığınız bir dizini saklamayın.
depolama maliyeti oluşturmaya devam eder.
Çok sütunlu dizinler oluşturma
Sorgularınız birden çok sütunu birleştiriyorsa, çok sütunlu dizinleri kullanabilirsiniz. Ayrıca, bir dış sütunda da bir dizin kullanabilirsiniz ve iç aramanın doğrusal tarama olarak yapılmasını sağlayın.
Örneğin, aşağıdaki sorgu verildiğinde:
SELECT id, name
WHERE city = 'London, England'
ORDER BY city, name
Çok sütunlu bir dizinle sorguyu aşağıdaki sırayla hızlandırabilirsiniz: sorguda belirtildiği gibi:
CREATE INDEX city_name_index ON Customers(city, name);
Ancak yalnızca city
üzerinde bir dizininiz varsa dış sipariş yine de hızlandırılır. İç sipariş ise doğrusal tarama gerektirir.
Bu, önekli sorgularda da çalışır. Örneğin,
ON Customers (city, name)
; filtreleme, sıralama ve gruplandırmayı da hızlandırır
city
değerine göre; çünkü çok sütunlu bir dizine ait dizin tablosu
belirli bir sırada gösterir.
WITHOUT ROWID
ürününü düşünün
Varsayılan olarak SQLite, tablonuz için bir rowid
sütunu oluşturur. Burada rowid
, varsayılan olarak bir
dolaylı INTEGER PRIMARY KEY AUTOINCREMENT
. Varsayılan
INTEGER PRIMARY KEY
ise bu sütun rowid
için takma ad olur.
INTEGER
dışında bir birincil anahtarı veya sütunlardan oluşan bir karma anahtarı olan tablolar için WITHOUT
ROWID
'i kullanın.
Küçük verileri BLOB
, büyük verileri ise dosya olarak depolayın
Bir satırla ilişkilendirmek istediğiniz büyük veriler (ör. bir resmin küçük resmi veya bir kişinin fotoğrafı) varsa verileri bir BLOB
sütununda ya da dosyada saklayabilir ve ardından dosya yolunu sütunda saklayabilirsiniz.
Dosyalar genellikle 4 KB'lık artışlarla yuvarlanır. Çok küçük dosyalar için
çok büyükse, yuvarlama hatasını büyük bir bölmede
BLOB
olarak veritabanını kullanabilirsiniz. SQLite, dosya sistemi çağrılarını en aza indirir ve
temel dosya sistemi
bazı durumlarda kullanabilirsiniz.
Sorgu performansını iyileştirme
Şu en iyi uygulamaları izleyerek SQLite'ta sorgu performansını artırmak için ve işlem verimliliğini en üst düzeye çıkarıyor.
Yalnızca ihtiyacınız olan satırları okuma
Filtreler, belirli kriterler belirleyerek sonuçlarınızı daraltmanıza olanak tanır. (ör. tarih aralığı, konum veya ad) Sınırlar, sayıyı kontrol etmenize olanak tanır gösterilen sonuçlar:
Kotlin
db.rawQuery(""" SELECT name FROM Customers LIMIT 10; """.trimIndent(), null ).use { cursor -> while (cursor.moveToNext()) { ... } }
Java
try (Cursor cursor = db.rawQuery(""" SELECT name FROM Customers LIMIT 10; """, null)) { while (cursor.moveToNext()) { ... } }
Yalnızca ihtiyacınız olan sütunları okuyun
Gereksiz sütunlar seçmekten kaçının, aksi takdirde sorgularınızı yavaşlatabilir ve kaynaklarınızı israfa uğratabilir. Bunun yerine yalnızca sütunları seçin için de geçerli.
Aşağıdaki örnekte id
, name
ve phone
'yi seçiyorsunuz:
Kotlin
// This is not the most efficient way of doing this. // See the following example for a better approach. db.rawQuery( """ SELECT id, name, phone FROM customers; """.trimIndent(), null ).use { cursor -> while (cursor.moveToNext()) { val name = cursor.getString(1) // ... } }
Java
// This is not the most efficient way of doing this. // See the following example for a better approach. try (Cursor cursor = db.rawQuery(""" SELECT id, name, phone FROM customers; """, null)) { while (cursor.moveToNext()) { String name = cursor.getString(1); ... } }
Ancak, yalnızca name
sütununa ihtiyacınız vardır:
Kotlin
db.rawQuery(""" SELECT name FROM Customers; """.trimIndent(), null ).use { cursor -> while (cursor.moveToNext()) { val name = cursor.getString(0) ... } }
Java
try (Cursor cursor = db.rawQuery(""" SELECT name FROM Customers; """, null)) { while (cursor.moveToNext()) { String name = cursor.getString(0); ... } }
Sorguları Dize birleştirmeyle değil, SQL Kartları ile parametrelere dönüştürün
Sorgu dizeniz yalnızca çalışma zamanında bilinen bir parametre içerebilir. Örneğin, şu şekildedir:
Kotlin
fun getNameById(id: Long): String? db.rawQuery( "SELECT name FROM customers WHERE id=$id", null ).use { cursor -> return if (cursor.moveToFirst()) { cursor.getString(0) } else { null } } }
Java
@Nullable public String getNameById(long id) { try (Cursor cursor = db.rawQuery( "SELECT name FROM customers WHERE id=" + id, null)) { if (cursor.moveToFirst()) { return cursor.getString(0); } else { return null; } } }
Önceki kodda, her sorgu farklı bir dize oluşturur. Bu nedenle,
, ekstre önbelleğinden yararlanmaz. Her çağrıda derleme için SQLite gerekir
çalışmasını sağlamalısınız. Bunun yerine, id
bağımsız değişkenini bir parametre ile değiştirebilir ve değeri selectionArgs
ile bağlayabilirsiniz:
Kotlin
fun getNameById(id: Long): String? { db.rawQuery( """ SELECT name FROM customers WHERE id=? """.trimIndent(), arrayOf(id.toString()) ).use { cursor -> return if (cursor.moveToFirst()) { cursor.getString(0) } else { null } } }
Java
@Nullable public String getNameById(long id) { try (Cursor cursor = db.rawQuery(""" SELECT name FROM customers WHERE id=? """, new String[] {String.valueOf(id)})) { if (cursor.moveToFirst()) { return cursor.getString(0); } else { return null; } } }
Artık sorgu bir kez derlenebilir ve önbelleğe alınabilir. Derlenen sorgu yeniden kullanılıyor
farklı getNameById(long)
çağrıları arasında.
Kodda değil, SQL'de yineleme
Programatik yerine, hedeflenen tüm sonuçları döndüren tek bir sorgu kullan Bağımsız sonuçlar döndürmek için SQL sorgularında döngü yineleme. Programatik döngü, tek bir SQL sorgusundan yaklaşık 1.000 kat daha yavaştır.
Benzersiz değerler için DISTINCT
kullanın
DISTINCT
anahtar kelimesini kullanmak, işlenecek veri miktarını azaltarak sorgularınızın performansını artırabilir. Örneğin,
bir sütundan yalnızca benzersiz değerleri döndürmek için DISTINCT
işlevini kullanın:
Kotlin
db.rawQuery(""" SELECT DISTINCT name FROM Customers; """.trimIndent(), null ).use { cursor -> while (cursor.moveToNext()) { // Only iterate over distinct names in Kotlin ... } }
Java
try (Cursor cursor = db.rawQuery(""" SELECT DISTINCT name FROM Customers; """, null)) { while (cursor.moveToNext()) { // Only iterate over distinct names in Java ... } }
Mümkün olduğunda toplama işlevlerini kullanın
Satır verileri içermeyen birleştirilmiş sonuçlar için toplama işlevlerini kullanın. Örneğin, aşağıdaki kod, en az bir eşleşen satır olup olmadığını kontrol eder:
Kotlin
// This is not the most efficient way of doing this. // See the following example for a better approach. db.rawQuery(""" SELECT id, name FROM Customers WHERE city = 'Paris'; """.trimIndent(), null ).use { cursor -> if (cursor.moveToFirst()) { // At least one customer from Paris ... } else { // No customers from Paris ... }
Java
// This is not the most efficient way of doing this. // See the following example for a better approach. try (Cursor cursor = db.rawQuery(""" SELECT id, name FROM Customers WHERE city = 'Paris'; """, null)) { if (cursor.moveToFirst()) { // At least one customer from Paris ... } else { // No customers from Paris ... } }
Yalnızca ilk satırı almak için EXISTS()
kullanabilirsiniz. Eşleşen bir satır yoksa 0
, bir veya daha fazla satır eşleşirse 1
döndürülür:
Kotlin
db.rawQuery(""" SELECT EXISTS ( SELECT null FROM Customers WHERE city = 'Paris'; ); """.trimIndent(), null ).use { cursor -> if (cursor.moveToFirst() && cursor.getInt(0) == 1) { // At least one customer from Paris ... } else { // No customers from Paris ... } }
Java
try (Cursor cursor = db.rawQuery(""" SELECT EXISTS ( SELECT null FROM Customers WHERE city = 'Paris' ); """, null)) { if (cursor.moveToFirst() && cursor.getInt(0) == 1) { // At least one customer from Paris ... } else { // No customers from Paris ... } }
SQLite toplama özelliğini kullanma işlevleriyle ilgili daha fazla bilgi edinin. kod:
COUNT
: Bir sütunda kaç satır olduğunu sayar.SUM
: Bir sütundaki tüm sayısal değerleri ekler.MIN
veyaMAX
: En düşük veya en yüksek değeri belirler. Sayısal sütunlar,DATE
türleri ve metin türleri için çalışır.AVG
: Ortalama sayısal değeri bulur.GROUP_CONCAT
: Dizeleri isteğe bağlı bir ayırıcıyla birleştirir.
Cursor.getCount()
yerine COUNT()
kullanın
Aşağıdaki örnekte, Cursor.getCount()
işlevi veritabanındaki tüm satırları okur ve tüm satır değerlerini döndürür:
Kotlin
// This is not the most efficient way of doing this. // See the following example for a better approach. db.rawQuery(""" SELECT id FROM Customers; """.trimIndent(), null ).use { cursor -> val count = cursor.getCount() }
Java
// This is not the most efficient way of doing this. // See the following example for a better approach. try (Cursor cursor = db.rawQuery(""" SELECT id FROM Customers; """, null)) { int count = cursor.getCount(); ... }
Ancak COUNT()
kullanıldığında, veritabanı yalnızca
sayı:
Kotlin
db.rawQuery(""" SELECT COUNT(*) FROM Customers; """.trimIndent(), null ).use { cursor -> cursor.moveToFirst() val count = cursor.getInt(0) }
Java
try (Cursor cursor = db.rawQuery(""" SELECT COUNT(*) FROM Customers; """, null)) { cursor.moveToFirst(); int count = cursor.getInt(0); ... }
Kod yerine Nest sorguları
SQL composable'dır ve alt sorguları, birleştirmeleri ve yabancı anahtar kısıtlamalarını destekler. Bir sorgunun sonucunu, uygulamaya gitmeden başka bir sorguda kullanabilirsiniz. girin. Bu sayede SQLite'dan veri kopyalama ihtiyacı azalır ve veritabanı Google Analytics 4.0'dan ibarettir.
Aşağıdaki örnekte, şehirdeki en büyük şehirleri bulmak için sonra bu sonucu başka bir sorguda kullanarak şu şehir:
Kotlin
// This is not the most efficient way of doing this. // See the following example for a better approach. db.rawQuery(""" SELECT city FROM Customers GROUP BY city ORDER BY COUNT(*) DESC LIMIT 1; """.trimIndent(), null ).use { cursor -> if (cursor.moveToFirst()) { val topCity = cursor.getString(0) db.rawQuery(""" SELECT name, city FROM Customers WHERE city = ?; """.trimIndent(), arrayOf(topCity)).use { innerCursor -> while (innerCursor.moveToNext()) { ... } } } }
Java
// This is not the most efficient way of doing this. // See the following example for a better approach. try (Cursor cursor = db.rawQuery(""" SELECT city FROM Customers GROUP BY city ORDER BY COUNT(*) DESC LIMIT 1; """, null)) { if (cursor.moveToFirst()) { String topCity = cursor.getString(0); try (Cursor innerCursor = db.rawQuery(""" SELECT name, city FROM Customers WHERE city = ?; """, new String[] {topCity})) { while (innerCursor.moveToNext()) { ... } } } }
Önceki örneğin yarısında sonucu almak için tek bir SQL kullanın iç içe yerleştirilmiş ifadeler içeren bir sorgu:
Kotlin
db.rawQuery(""" SELECT name, city FROM Customers WHERE city IN ( SELECT city FROM Customers GROUP BY city ORDER BY COUNT (*) DESC LIMIT 1; ); """.trimIndent(), null ).use { cursor -> if (cursor.moveToNext()) { ... } }
Java
try (Cursor cursor = db.rawQuery(""" SELECT name, city FROM Customers WHERE city IN ( SELECT city FROM Customers GROUP BY city ORDER BY COUNT(*) DESC LIMIT 1 ); """, null)) { while(cursor.moveToNext()) { ... } }
SQL'deki benzersizliği kontrol edin
Belirli bir sütun değerinin bir sütun haline getirirse, bu benzersizliği bir sütun olarak uygulamak daha verimli olabilir. kısıtlayın.
Aşağıdaki örnekte, oluşturulacak satırı doğrulamak için bir sorgu çalıştırılmıştır eklendi:
Kotlin
// This is not the most efficient way of doing this. // See the following example for a better approach. db.rawQuery( """ SELECT EXISTS ( SELECT null FROM customers WHERE username = ? ); """.trimIndent(), arrayOf(customer.username) ).use { cursor -> if (cursor.moveToFirst() && cursor.getInt(0) == 1) { throw AddCustomerException(customer) } } db.execSQL( "INSERT INTO customers VALUES (?, ?, ?)", arrayOf( customer.id.toString(), customer.name, customer.username ) )
Java
// This is not the most efficient way of doing this. // See the following example for a better approach. try (Cursor cursor = db.rawQuery(""" SELECT EXISTS ( SELECT null FROM customers WHERE username = ? ); """, new String[] { customer.username })) { if (cursor.moveToFirst() && cursor.getInt(0) == 1) { throw new AddCustomerException(customer); } } db.execSQL( "INSERT INTO customers VALUES (?, ?, ?)", new String[] { String.valueOf(customer.id), customer.name, customer.username, });
Kotlin veya Java'daki benzersiz kısıtlamayı kontrol etmek yerine, Tabloyu tanımladığınızda SQL:
CREATE TABLE Customers(
id INTEGER PRIMARY KEY,
name TEXT,
username TEXT UNIQUE
);
SQLite aşağıdakilerle aynı işlemleri yapar:
CREATE TABLE Customers(...);
CREATE UNIQUE INDEX CustomersUsername ON Customers(username);
Şimdi bir satır ekleyip SQLite'ın kısıtlamayı kontrol etmesini sağlayabilirsiniz:
Kotlin
try { db.execSql( "INSERT INTO Customers VALUES (?, ?, ?)", arrayOf(customer.id.toString(), customer.name, customer.username) ) } catch(e: SQLiteConstraintException) { throw AddCustomerException(customer, e) }
Java
try { db.execSQL( "INSERT INTO Customers VALUES (?, ?, ?)", new String[] { String.valueOf(customer.id), customer.name, customer.username, }); } catch (SQLiteConstraintException e) { throw new AddCustomerException(customer, e); }
SQLite, birden çok sütunlu benzersiz dizinleri destekler:
CREATE TABLE table(...);
CREATE UNIQUE INDEX unique_table ON table(column1, column2, ...);
SQLite, kısıtlamaları Kotlin veya Java'ya göre daha hızlı ve daha az ek yük ile doğrular girin. Uygulama kodu yerine SQLite kullanmak en iyi uygulamalardan biridir.
Tek bir işlemde birden çok ekleme işlemi yapma
Bir işlem birden fazla işlem gerçekleştirir, bu da hem de doğruluğu kapsar. Veri tutarlılığını artırmak ve performansı artırmak istiyorsanız toplu eklemeler yapabilirsiniz:
Kotlin
db.beginTransaction() try { customers.forEach { customer -> db.execSql( "INSERT INTO Customers VALUES (?, ?, ...)", arrayOf(customer.id.toString(), customer.name, ...) ) } } finally { db.endTransaction() }
Java
db.beginTransaction(); try { for (customer : Customers) { db.execSQL( "INSERT INTO Customers VALUES (?, ?, ...)", new String[] { String.valueOf(customer.id), customer.name, ... }); } } finally { db.endTransaction() }
Sorun giderme araçlarını kullanma
SQLite, performansı ölçmeye yardımcı olmak için aşağıdaki sorun giderme araçlarını sunar.
SQLite'in etkileşimli istemlerini kullanma
Sorgu çalıştırmak ve bilgi edinmek için makinenizde SQLite çalıştırın.
Farklı Android platform sürümlerinde SQLite'ın farklı revizyonları kullanılır. Android destekli bir cihazdakiyle aynı motoru kullanmak için adb shell
'ü kullanın ve hedef cihazınızda sqlite3
'ü çalıştırın.
SQLite'tan sorguları zamanlamasını isteyebilirsiniz:
sqlite> .timer on
sqlite> SELECT ...
Run Time: real ... user ... sys ...
EXPLAIN QUERY PLAN
SQLite'tan bir sorguyu
EXPLAIN QUERY PLAN
:
sqlite> EXPLAIN QUERY PLAN
SELECT id, name
FROM Customers
WHERE city = 'Paris';
QUERY PLAN
`--SCAN Customers
Önceki örnekte, tüm sonuçları bulmak için dizin olmadan tam bir tablo taraması yapılmalıdır. bir teklif eklediğinizden emin olun. Buna doğrusal karmaşıklık denir. SQLite'ın okuması gerekiyor tüm satırları kaldırın ve yalnızca Paris'teki müşterilerle eşleşen satırları tutun. Düzeltmek için dizin ekleyebilirsiniz:
sqlite> CREATE INDEX Idx1 ON Customers(city);
sqlite> EXPLAIN QUERY PLAN
SELECT id, name
FROM Customers
WHERE city = 'Paris';
QUERY PLAN
`--SEARCH test USING INDEX Idx1 (city=?
Etkileşimli kabuğu kullanıyorsanız SQLite'ten sorgu planlarını her zaman açıklamasını isteyebilirsiniz:
sqlite> .eqp on
Daha fazla bilgi için bkz. Sorgu Planlama.
SQLite Analiz Aracı
SQLite,
sqlite3_analyzer
komut satırı arayüzü (KSA) kullanarak,
performans sorunlarını gidermeye yardımcı olur. Yüklemek için
SQLite İndirme Sayfası.
Bir hedef cihazdan cihazınıza veritabanı indirmek için adb pull
kullanabilirsiniz
analiz için iş istasyonu:
adb pull /data/data/<app_package_name>/databases/<db_name>.db
SQLite Tarayıcı
GUI aracını da yükleyebilirsiniz SQLite üzerinde SQLite Tarayıcı İndirilenler sayfası.
Android günlük kaydı
Android, SQLite sorgularını zamanlayıp sizin için günlüğe kaydeder:
# Enable query time logging
$ adb shell setprop log.tag.SQLiteTime VERBOSE
# Disable query time logging
$ adb shell setprop log.tag.SQLiteTime ERROR
```### Perfetto tracing
### Perfetto tracing {:#perfetto-tracing}
When [configuring Perfetto](https://perfetto.dev/docs/concepts/config), you may
add the following to include tracks for individual queries:
```protobuf
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
atrace_categories: "database"
}
}
}
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Sürekli Entegrasyon'da karşılaştırmalar çalıştırma
- Donmuş kare
- Macrobenchmark olmadan Temel Profiller oluşturma ve ölçme