Android, verimli bir SQL veritabanı olan SQLite için yerleşik destek sunar. Uygulamanızın performansını optimize etmek için aşağıdaki en iyi uygulamaları izleyin. Böylece, verileriniz büyüdükçe uygulamanızın hızlı ve öngörülebilir şekilde hızlı kalmasını sağlayabilirsiniz. Bu en iyi uygulamaları kullanarak, yeniden üretilmesi ve sorun giderilmesi zor olan performans sorunlarıyla 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 gerekli verileri alacak şekilde optimize edin. Veritabanından okunan veri miktarını en aza indirin. Çünkü aşırı veri alma işlemi performansı etkileyebilir.
İşi SQLite motoruna aktarma: SQL sorgularında hesaplama, filtreleme ve sıralama işlemleri gerçekleştirin. SQLite'ın sorgu motorunu kullanmak performansı önemli ölçüde artırabilir.
Veritabanı şemasını değiştirme: SQLite'ın etkili sorgu planları ve veri temsilleri oluşturmasına yardımcı olmak için veritabanı şemanızı tasarlayın. Performansı artırmak için tabloları düzgün şekilde dizine ekleyin ve tablo yapılarını optimize edin.
Ayrıca, optimizasyon gerektiren alanları belirlemeye yardımcı olmak için SQLite veritabanınızın performansını ölçmek üzere mevcut sorun giderme araçlarını kullanabilirsiniz.
Jetpack Room kitaplığını kullanmanızı öneririz.
Veritabanını performans için yapılandırma
SQLite'te optimum performans için veritabanınızı yapılandırmak üzere bu bölümdeki adımları uygulayın.
Yazma öncesi günlük kaydını etkinleştirme
SQLite, mutasyonları bir günlük dosyasına ekleyerek uygular. Bu günlük dosyası, zaman zaman veritabanında sıkıştırılır. Buna Yazma Öncesi Günlük Kaydı (WAL) denir.
ATTACH DATABASE kullanmıyorsanız WAL'ı etkinleştirin.
Senkronizasyon modunu rahatlatma
WAL kullanılırken varsayılan olarak her commit, verilerin diske ulaşmasını sağlamak için bir fsync yayınlar. Bu, verilerin dayanıklılığını artırır ancak işlemelerinizi yavaşlatır.
SQLite'ta senkron modu kontrol etme seçeneği vardır. WAL'ı etkinleştirirseniz senkron modu NORMAL olarak ayarlayın:
// When opening the database
val paramsBuilder: SQLiteDatabase.OpenParams.Builder = SQLiteDatabase.OpenParams.Builder()
paramsBuilder.journalMode = SQLiteDatabase.SYNC_MODE_NORMAL
// Or: after having opened the database
db.execSQL("PRAGMA synchronous = NORMAL");
Bu ayarda, veriler diske depolanmadan önce bir işlem döndürülebilir. Güç kaybı veya çekirdek panik gibi bir cihaz kapatma işlemi gerçekleşirse kaydedilen veriler kaybolabilir. Ancak günlük kaydı nedeniyle veritabanınız bozulmaz.
Yalnızca uygulamanız kilitlenirse verileriniz diske ulaşmaya devam eder. Çoğu uygulama için bu ayar, önemli 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ı tanımlayın. SQLite, verimli sorgu planları ve veriler oluşturarak daha hızlı veri alımına olanak tanır. Bu bölümde, tablo şemaları oluşturmayla ilgili en iyi uygulamalar verilmiştir.
INTEGER PRIMARY KEY kategorisini düşünün
Bu örnek için bir tabloyu aşağıdaki gibi tanımlayın ve 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 çıkışı aşağıdaki gibidir:
| rowid | id | ad | şehir |
|---|---|---|---|
| 1 | 456 | John Lennon | Liverpool, İngiltere |
| 2 | 123 | Michael Jackson | Gary, IN |
| 3 | 789 | Dolly Parton | Sevier County, TN |
rowid sütunu, ekleme sırasını koruyan bir dizindir. rowid ile filtreleyen sorgular hızlı bir B-ağacı araması olarak uygulanır ancak id ile filtreleyen sorgular yavaş bir tablo taramasıdır.
id ile arama yapmayı planlıyorsanız depolama alanında daha az veri ve genel olarak daha hızlı bir veritabanı için rowid sütununu depolamaktan kaçınabilirsiniz:
CREATE TABLE Customers(
id INTEGER PRIMARY KEY,
name TEXT,
city TEXT
);
Tablonuz artık aşağıdaki gibi görünüyor:
| id | ad | şehir |
|---|---|---|
| 123 | Michael Jackson | Gary, IN |
| 456 | John Lennon | Liverpool, İngiltere |
| 789 | Dolly Parton | Sevier County, TN |
rowid sütununu saklamanız gerekmediğinden id sorguları hızlıdır. Tablonun artık kampanya siparişi yerine id temelinde sıralandığını unutmayın.
Dizinlerle sorguları hızlandırma
SQLite, sorguları hızlandırmak için dizinleri kullanır. Bir sütun filtrelenirken (WHERE), sıralanırken (ORDER BY) veya toplanırken (GROUP BY) tabloda sütun için bir dizin varsa sorgu hızlandırılır.
Önceki örnekte, city ile 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);
Dizin, dizin sütununa göre sıralanmış ve rowid ile eşlenmiş ek bir tablo olarak uygulanır:
| şehir | rowid |
|---|---|
| Gary, IN | 2 |
| Liverpool, İngiltere | 1 |
| Sevier County, TN | 3 |
city sütununun depolama maliyetinin artık iki katına çıktığını unutmayın. Bunun nedeni, sütunun hem orijinal tabloda hem de dizinde bulunmasıdır. Dizini kullandığınız için eklenen depolama alanının maliyeti, daha hızlı sorguların avantajına değer.
Ancak sorgu performansı artışı olmadan depolama maliyeti ödememek için kullanmadığınız bir dizini korumayın.
Çok sütunlu dizinler oluşturma
Sorgularınız birden fazla sütunu birleştiriyorsa sorguyu tam olarak hızlandırmak için çok sütunlu dizinler oluşturabilirsiniz. Ayrıca, dış sütunda bir dizin kullanabilir ve iç aramanın doğrusal tarama olarak yapılmasını sağlayabilirsiniz.
Örneğin, şu sorgu verildiğinde:
SELECT id, name
WHERE city = 'London, England'
ORDER BY city, name
Sorguda belirtilen sırayla çok sütunlu bir dizin kullanarak sorguyu hızlandırabilirsiniz:
CREATE INDEX city_name_index ON Customers(city, name);
Ancak yalnızca city üzerinde bir dizininiz varsa dış sıralama yine hızlandırılırken iç sıralama için doğrusal tarama gerekir.
Bu özellik, önek sorgularıyla da çalışır. Örneğin, bir dizin
ON Customers (city, name), çok sütunlu bir dizinin dizin tablosu belirli bir sırayla belirli dizinlere göre sıralandığından city ile filtreleme, sıralama ve gruplandırma işlemlerini de hızlandırır.
WITHOUT ROWID kategorisini düşünün
SQLite, varsayılan olarak tablonuz için bir rowid sütunu oluşturur. Burada rowid, örtülü bir INTEGER PRIMARY KEY AUTOINCREMENT'dir. Zaten INTEGER PRIMARY KEY olan bir sütununuz varsa bu sütun, rowid'nin takma adı olur.
INTEGER dışında bir birincil anahtarı olan veya sütunların bileşimi olan tablolar için WITHOUT ROWID'ı kullanabilirsiniz.
Küçük verileri BLOB olarak, büyük verileri ise dosya olarak depolama
Bir satırla büyük verileri (ör. resmin küçük resmi veya bir kişi için fotoğraf) ilişkilendirmek istiyorsanız verileri BLOB sütununda veya bir dosyada saklayıp yolu sütunda saklayabilirsiniz.
Dosyalar genellikle 4 KB'lık artışlarla yuvarlanır. Yuvarlama hatasının önemli olduğu çok küçük dosyaları veritabanında BLOB olarak depolamak daha verimlidir. SQLite, dosya sistemi çağrılarını en aza indirir ve bazı durumlarda temel dosya sisteminden daha hızlıdır.
Sorgu performansını artırma
Yanıt sürelerini en aza indirerek ve işlem verimliliğini en üst düzeye çıkararak SQLite'te sorgu performansını artırmak için aşağıdaki en iyi uygulamalardan yararlanın.
Yalnızca ihtiyacınız olan satırları okuma
Filtreler, tarih aralığı, konum veya ad gibi belirli ölçütleri belirterek sonuçlarınızı daraltmanıza olanak tanır. Sınırlar, gördüğünüz sonuçların sayısını kontrol etmenize olanak tanır:
db.rawQuery("""
SELECT name
FROM Customers
LIMIT 10;
""".trimIndent(),
null
).use { cursor ->
while (cursor.moveToNext()) {
// Process cursor data
}
}
Yalnızca ihtiyacınız olan sütunları okuma
Gereksiz sütunları seçmekten kaçının. Bu sütunlar sorgularınızı yavaşlatabilir ve kaynaklarınızı boşa harcayabilir. Bunun yerine, yalnızca kullanılan sütunları seçin.
Aşağıdaki örnekte id, name ve phone'yi seçiyorsunuz:
// 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)
// Further processing
}
}
Ancak yalnızca name sütununa ihtiyacınız vardır:
db.rawQuery("""
SELECT name
FROM Customers;
""".trimIndent(),
null
).use { cursor ->
while (cursor.moveToNext()) {
val name = cursor.getString(0)
// Further processing
}
}
Sorguları parametrelendirme
Sorgu dizeniz, yalnızca çalışma zamanında bilinen bir parametre içerebilir. Örneğin:
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
}
}
}
Önceki kodda her sorgu farklı bir dize oluşturur ve bu nedenle ifade önbelleğinden yararlanmaz. Her çağrının yürütülebilmesi için önce SQLite tarafından derlenmesi gerekir. Bunun yerine, id bağımsız değişkenini bir parametreyle değiştirebilir ve değeri selectionArgs ile bağlayabilirsiniz:
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
}
}
}
Artık sorgu bir kez derlenip önbelleğe alınabilir. Derlenen sorgu, getNameById(long) öğesinin farklı çağrıları arasında yeniden kullanılır.
Kodda değil SQL'de yineleme yapın
Tek tek sonuçları döndürmek için SQL sorgularında yineleme yapan programatik bir döngü yerine, hedeflenen tüm sonuçları döndüren tek bir sorgu kullanın. 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şlenmesi gereken veri miktarını azaltarak sorgularınızın performansını artırabilir. Örneğin, bir sütundaki yalnızca benzersiz değerleri döndürmek istiyorsanız DISTINCT işlevini kullanın:
db.rawQuery("""
SELECT DISTINCT name
FROM Customers;
""".trimIndent(),
null
).use { cursor ->
while (cursor.moveToNext()) {
// Only iterate over distinct names in Kotlin
// Process distinct name
}
}
Mümkün olduğunda toplama işlevlerini kullanın
Satır verileri olmadan toplu 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:
// 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
// Handle found
} else {
// No customers from Paris
// Handle not found
}
Yalnızca ilk satırı getirmek için eşleşen bir satır yoksa 0, bir veya daha fazla satır eşleşiyorsa 1 döndürmek üzere EXISTS() işlevini kullanabilirsiniz:
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
// Handle found
} else {
// No customers from Paris
// Handle not found
}
}
Uygulama kodunuzda SQLite toplama işlevlerini kullanın:
COUNT: Bir sütunda kaç satır olduğunu sayar.SUM: Bir sütundaki tüm sayısal değerleri toplar.MINveyaMAX: En düşük ya da en yüksek değeri belirler. Sayısal sütunlar,DATEtürleri ve metin türleri için çalışır.AVG: Sayısal değerin ortalamasını 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:
// 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()
// Use count
}
Ancak COUNT() kullanıldığında veritabanı yalnızca sayıyı döndürür:
db.rawQuery("""
SELECT COUNT(*)
FROM Customers;
""".trimIndent(),
null
).use { cursor ->
cursor.moveToFirst()
val count = cursor.getInt(0)
// Use count
}
Kod yerine iç içe yerleştirilmiş sorgular
SQL, birleştirilebilir ve alt sorguları, birleştirmeleri ve yabancı anahtar kısıtlamalarını destekler. Uygulama koduna gitmeden bir sorgunun sonucunu başka bir sorguda kullanabilirsiniz. Bu, SQLite'tan veri kopyalama ihtiyacını azaltır ve veritabanı motorunun sorgunuzu optimize etmesine olanak tanır.
Aşağıdaki örnekte, en çok müşteriye sahip olan şehri bulmak için bir sorgu çalıştırabilir, ardından bu şehirden tüm müşterileri bulmak için sonucu başka bir sorguda kullanabilirsiniz:
// 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()) {
// Process inner cursor data
}
}
}
}
Sonucu önceki örneğin yarısı kadar sürede almak için iç içe yerleştirilmiş ifadeler içeren tek bir SQL sorgusu kullanın:
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()) {
// Process cursor data
}
}
SQL'de benzersizliği kontrol etme
Bir satırın, belirli bir sütun değeri tabloda benzersiz olmadığı sürece eklenmemesi gerekiyorsa bu benzersizliği sütun kısıtlaması olarak zorunlu kılmak daha verimli olabilir.
Aşağıdaki örnekte, eklenecek satırı doğrulamak için bir sorgu, eklemek için ise başka bir sorgu çalıştırılır:
// 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
)
)
Kotlin'de benzersiz kısıtlamayı kontrol etmek yerine tabloyu tanımlarken SQL'de kontrol edebilirsiniz:
CREATE TABLE Customers(
id INTEGER PRIMARY KEY,
name TEXT,
username TEXT UNIQUE
);
SQLite, aşağıdakilerle aynı işlemi yapar:
CREATE TABLE Customers(...);
CREATE UNIQUE INDEX CustomersUsername ON Customers(username);
Artık bir satır ekleyebilir ve kısıtlamayı SQLite'ın kontrol etmesine izin verebilirsiniz:
try {
db.execSql(
"INSERT INTO Customers VALUES (?, ?, ?)",
arrayOf(customer.id.toString(), customer.name, customer.username)
)
} catch(e: SQLiteConstraintException) {
throw AddCustomerException(customer, e)
}
SQLite, birden çok sütun içeren benzersiz dizinleri destekler:
CREATE TABLE table(...);
CREATE UNIQUE INDEX unique_table ON table(column1, column2, ...);
SQLite, kısıtlamaları Kotlin koduna kıyasla daha hızlı ve daha az ek yükle doğrular. Uygulama kodu yerine SQLite kullanmak en iyi uygulamadır.
Tek bir işlemde birden fazla ekleme işlemini toplu olarak gerçekleştirme
Bir işlem, birden fazla işlemi yürütür. Bu da yalnızca verimliliği değil, doğruluğu da artırır. Veri tutarlılığını artırmak ve performansı hızlandırmak için eklemeleri toplu olarak yapabilirsiniz:
db.beginTransaction()
try {
customers.forEach { customer ->
db.execSql(
"INSERT INTO Customers VALUES (?, ?, ?)",
arrayOf(customer.id.toString(), customer.name, "customerValue")
)
}
} finally {
db.endTransaction()
}
Sorun giderme araçlarını kullanma
SQLite, performansı ölçmenize yardımcı olmak için aşağıdaki sorun giderme araçlarını sağlar.
SQLite'ın etkileşimli istemini kullanma
Sorgu çalıştırmak ve öğrenmek için makinenizde SQLite'ı çalıştırın.
Farklı Android platform sürümleri, SQLite'ın farklı düzeltmelerini kullanır. Android destekli bir cihazdaki motoru kullanmak için adb shell kullanın ve hedef cihazınızda sqlite3 komutunu çalıştırın.
SQLite'tan sorguların süresini ölçmesini isteyebilirsiniz:
sqlite> .timer on
sqlite> SELECT ...
Run Time: real ... user ... sys ...
EXPLAIN QUERY PLAN
SQLite'tan EXPLAIN QUERY PLAN kullanarak bir sorguyu nasıl yanıtlayacağını açıklamasını isteyebilirsiniz:
sqlite> EXPLAIN QUERY PLAN
SELECT id, name
FROM Customers
WHERE city = 'Paris';
QUERY PLAN
`--SCAN Customers
Önceki örnekte, Paris'teki tüm müşterileri bulmak için dizin olmadan tam tablo taraması yapılması gerekir. Buna doğrusal karmaşıklık denir. SQLite'ın tüm satırları okuması ve yalnızca Paris'teki müşterilerle eşleşen satırları tutması gerekir. Bu sorunu 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'tan her zaman sorgu planlarını açıklamasını isteyebilirsiniz:
sqlite> .eqp on
Daha fazla bilgi için Sorgu Planlama bölümüne bakın.
SQLite Analiz Aracı
SQLite, performansla ilgili sorunları gidermek için kullanılabilecek ek bilgileri boşaltmak üzere sqlite3_analyzer komut satırı arayüzünü (KSA) sunar. Yüklemek için SQLite İndirme Sayfası'nı ziyaret edin.
Bir veritabanı dosyasını hedef cihazdan iş istasyonunuza indirip analiz etmek için adb pull simgesini kullanabilirsiniz:
adb pull /data/data/<app_package_name>/databases/<db_name>.db
SQLite Browser
Ayrıca, SQLite Browser adlı GUI aracını SQLite İndirmeler sayfasından da yükleyebilirsiniz.
Android günlük kaydı
Android, SQLite sorgularının süresini ölçer ve bunları 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 izleme
Perfetto'yu yapılandırırken, tek tek sorgular için izlemeleri dahil etmek üzere aşağıdakileri ekleyebilirsiniz:
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
atrace_categories: "database"
}
}
}
dumpsys meminfo
adb shell dumpsys meminfo <package-name>, SQLite belleğiyle ilgili bazı ayrıntılar da dahil olmak üzere uygulamanın bellek kullanımıyla ilgili istatistikleri yazdırır. Örneğin, bu, bir geliştiricinin cihazında adb shell dumpsys meminfo com.google.android.gms.persistent komutunun çıkışından alınmıştır:
DATABASES
pgsz dbsz Lookaside(b) cache hits cache misses cache size Dbname
PER CONNECTION STATS
4 52 45 8 41 6 /data/user/10/com.google.android.gms/databases/gaia-discovery
4 8 0 0 0 (attached) temp
4 52 56 5 23 6 /data/user/10/com.google.android.gms/databases/gaia-discovery (1)
4 252 95 233 124 12 /data/user_de/10/com.google.android.gms/databases/phenotype.db
4 8 0 0 0 (attached) temp
4 252 17 0 17 1 /data/user_de/10/com.google.android.gms/databases/phenotype.db (1)
4 9280 105 103169 69805 25 /data/user/10/com.google.android.gms/databases/phenotype.db
4 20 0 0 0 (attached) temp
4 9280 108 13877 6394 25 /data/user/10/com.google.android.gms/databases/phenotype.db (2)
4 8 0 0 0 (attached) temp
4 9280 105 12548 5519 25 /data/user/10/com.google.android.gms/databases/phenotype.db (3)
4 8 0 0 0 (attached) temp
4 9280 107 18328 7886 25 /data/user/10/com.google.android.gms/databases/phenotype.db (1)
4 8 0 0 0 (attached) temp
4 36 51 156 29 5 /data/user/10/com.google.android.gms/databases/mobstore_gc_db_v0
4 36 97 47 27 10 /data/user/10/com.google.android.gms/databases/context_feature_default.db
4 36 56 3 16 4 /data/user/10/com.google.android.gms/databases/context_feature_default.db (2)
4 300 40 2111 24 5 /data/user/10/com.google.android.gms/databases/gservices.db
4 300 39 3 17 4 /data/user/10/com.google.android.gms/databases/gservices.db (1)
4 20 17 0 14 1 /data/user/10/com.google.android.gms/databases/gms.notifications.db
4 20 33 1 15 2 /data/user/10/com.google.android.gms/databases/gms.notifications.db (1)
4 120 40 143 163 4 /data/user/10/com.google.android.gms/databases/android_pay
4 120 123 86 32 19 /data/user/10/com.google.android.gms/databases/android_pay (1)
4 28 33 4 17 3 /data/user/10/com.google.android.gms/databases/googlesettings.db
POOL STATS
cache hits cache misses cache size Dbname
13 68 81 /data/user/10/com.google.android.gms/databases/gaia-discovery
233 145 378 /data/user_de/10/com.google.android.gms/databases/phenotype.db
147921 89616 237537 /data/user/10/com.google.android.gms/databases/phenotype.db
156 30 186 /data/user/10/com.google.android.gms/databases/mobstore_gc_db_v0
50 57 107 /data/user/10/com.google.android.gms/databases/context_feature_default.db
2114 43 2157 /data/user/10/com.google.android.gms/databases/gservices.db
1 31 32 /data/user/10/com.google.android.gms/databases/gms.notifications.db
229 197 426 /data/user/10/com.google.android.gms/databases/android_pay
4 18 22 /data/user/10/com.google.android.gms/databases/googlesettings.db
DATABASES bölümünde şunları bulabilirsiniz:
pgsz: Bir veritabanı sayfasının boyutu (KB cinsinden).dbsz: Veritabanının tamamının boyutu (sayfa olarak). Boyutu KB cinsinden almak içinpgsziledbszdeğerini çarpın.Lookaside(b): Bağlantı başına SQLite lookaside arabelleğine ayrılan bellek (bayt cinsinden). Bunlar genellikle çok küçüktür.cache hits: SQLite, veritabanı sayfalarının önbelleğini tutar. Bu, sayfa önbelleği isabetlerinin sayısıdır (sayım).cache misses: Sayfa önbelleği isabet etmeme sayısı (sayım).cache size: Önbellekteki sayfa sayısı (adet). Boyutu KB cinsinden almak için bu sayıyıpgszile çarpın.Dbname: DB dosyasının yolu. Örneğimizde, aynı temel veritabanına birden fazla bağlantı olduğunu belirtmek için bazı veritabanlarının adlarına(1)veya başka bir sayı eklenmiştir. İstatistikler bağlantı bazında izlenir.
POOL STATS bölümünde şunları bulabilirsiniz:
cache hits: SQLite, hazırlanan ifadeleri önbelleğe alır ve SQL ifadelerini derlerken biraz çaba ve bellek tasarrufu sağlamak için sorguları çalıştırırken bunları yeniden kullanmaya çalışır. Bu, ifade önbelleği isabetlerinin sayısıdır.cache misses: İfade önbelleği kaçırma sayısı (sayım).cache size: Android 17'den itibaren bu, önbellekteki toplam hazırlanmış ifade sayısını listeler. Önceki sürümlerde bu değer, diğer iki sütunda listelenen isabet ve ıskalama sayılarının toplamına eşittir ve önbellek boyutunu temsil etmez.
Ek kaynaklar
İçeriği görüntüleme
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- Sürekli entegrasyonda karşılaştırma testleri çalıştırma
- Donmuş kare
- Makro karşılaştırma testi olmadan temel profiller oluşturma ve ölçme