12 būdų, kaip optimizuoti SQLite duomenų bazes – išbandykite juos dabar!

Atskleidimas: Jūsų palaikymas padeda išlaikyti svetainę! Mes uždirbame siuntimo mokestį už kai kurias paslaugas, kurias rekomenduojame šiame puslapyje.


„SQLite“ yra SQL pagrindu sukurta reliacinių duomenų bazių valdymo sistema (RDBMS), įdiegta kaip įterpiama biblioteka. Ji saugo duomenų bazes kaip atskirus failus, o ne remiasi kliento-serverio modeliu.

SQLite dažniausiai naudojamas trimis būdais:

  • Paprastas naudojimas yra idealus norint išbandyti duomenų bazę turinčias programas ir jas tikrinti.
  • Kadangi viskas saugoma vietoje, o pati biblioteka gali būti įdėta į programą, „SQLite“ taip pat dažnai naudojama kaip pagrindinė duomenų saugykla mažoms programoms, kurias vietoje naudoja vienas vartotojas. Tai apima tokias programas kaip adresų knygos, darbų sąrašai ar net el. Pašto skaitytojai.
  • Galiausiai, SQLite duomenų bazės dažnai naudojamos kaip konkrečios programos failo formatas. Tai ypač naudinga programose, kur išsaugotas failas yra sudėtingas projektas, o ne gana paprastas dokumentas. Šiuo atveju kiekvienas programos sukurtas failas iš tikrųjų yra visa „SQLite“ duomenų bazė.

Optimizavimo poreikis

Didžiąją laiko dalį, kai jis naudojamas testavimui ir prototipų kūrimui, jo optimizavimas greičiui nėra labai svarbus. Tokiais atvejais taip pat ne visada įmanoma tai padaryti, nes galbūt planuojate savo programą paleisti naudodami kitą duomenų bazę. „SQLite“ čia paprasčiausiai naudojamas kaip kažkas kita, pavyzdžiui, „PostgreSQL“ ar „MySQL“.

Bet kai „SQLite“ naudojamas „gamyboje“, kaip ir antraisiais dviem atvejais, našumas yra svarbus. Kelių paprastų metodų pritaikymas gali iš tikrųjų paveikti duomenų bazių atnaujinimo ir užklausų greitį.

Čia yra keletas praktinių patarimų, kaip pagerinti SQLite našumą jūsų programose. Kai kurie iš jų yra SQL užklausų optimizavimas, kuris padėtų pagreitinti bet kurią SQL duomenų bazių sistemą. Kiti ypač stengiasi optimizuoti SQLite.

Kadangi „SQLite“ yra labai populiarus duomenų kaupiklis „Android“ programose, mes taip pat įtraukėme keletą konkrečių patarimų, kaip optimizuoti „SQLite“ našumą „Android“.

Naudokite operaciją

Pirmasis patarimas, kurį visi teikia pagreitinti „SQLite“, yra „naudoti operaciją“.

Visi tai sako, nes tai tikrai gera idėja. Bet jums gali kilti klausimas, kaip naudoti operaciją SQL.

Tarkime, kad jūs surinkote krūvą duomenų tam tikroje pasikartojančioje struktūroje, pavyzdžiui, sąraše ar masyve. Jums gali kilti pagunda peržvelgti savo duomenis ir įterpti juos į savo SQLite duomenų bazę kiekvienoje kilpos kartojime.

/ ************************************************** ***
Gaukite vardus ir pavardes iš failo, kuriame yra skirtukai.
Tada įdėkite juos į SQLlite duomenų bazę.
************************************** **** ** /

/ * būtinai apibrėžkite tai realiame gyvenime…
#define DUOMENŲ BAZĖ = // duomenų bazės pavadinimas //
#define FILE_OF_NAMES = // kelias į failą //
#define CREATE_TABLE = // SQL sakinys vardams kurti //
* /

„sqlite3_open“ (DUOMENŲ BAZĖ, &db);
„sqlite3_exec“ (db, CREATE_TABLE, NULL, NULL, &sErrMsg);

pFile = fopen (FILE_OF_NAMES,"r");
while (! feof (pFile)) {

„fgets“ („sInputBuf“, „BUFFER_SIZE“, „pFile“);

„sFirstName = strtok“ („sInputBuf“, "t");
sLastName = strtok (NULL, "t");

sprintf (sSQL, "ĮTERPTI Į VARDŲ VERTES (NULL, ‘% s’, ‘% s’,)", sFirstName, sLastName, s);
sqlite3_exec (db, sSQL, NULL, NULL, &sErrMsg);

n ++;
}
fklose (pFile);
„sqlite3_close“ (db);

Tai bloga mintis. Tai atomizuoja kiekvieną intarpą į vieną operaciją – kiekvienas su savo pridėtinėmis sąnaudomis. Nelabai svarbu, jei turite tik porą įdėklų, tačiau net greitai veikiančiame C kode tai gali sulėtinti greitį iki 100 įterpimų per sekundę. Jei naudojate „SQLite“ kaip programos failo formatą, vartotojams tai gali reikšti kelias sekundes vėlavimo kiekvieną kartą, kai jie išsaugo sudėtingą dokumentą ar projektą.

Užuot įdėję savo duomenų rinkinį atskirai, įvyniokite visus intarpus į vieną operaciją. Tai žymiai pagreitins įdėklus. Tai padaryti yra labai lengva.

/ * prieš ciklą – pradėkite operaciją * /
„sqlite3_exec“ (db, "PRADĖTI SANDORIUS", NULL, NULL, &sErrMsg);

pFile = fopen (FILE_OF_NAMES,"r");
while (! feof (pFile)) {
.
.
.
}

fklose (pFile);

/ * po ciklo – baigti operaciją * /
„sqlite3_exec“ (db, "Baigti sandorį", NULL, NULL, &sErrMsg);

Jūs vis dar vykdote INSERT teiginį kilpoje, tačiau jie neatnaujina duomenų bazės kiekvienoje pakartojime. Vietoj to, „SQLite“ išsaugo visus jūsų teiginius talpykloje ir visus juos vienu metu paleidžia kaip vieną operaciją, kai Baigote SANDORIĄ.

Kadangi visi įdėklai saugomi talpykloje, gali reikėti padidinti talpyklos dydį, kad būtų galima greičiau naudotis operacijomis tokiu būdu..

/ * atidarius db ryšį,
prieš pradedant operaciją * /
„sqlite3_exec“ (db, "PRAGMA talpyklos dydis = 10000", NULL, NULL, &sErrMsg);

Operacijos „Android“

„Android“ integruota „SQLite“ API leidžia dar lengviau naudoti operacijas.

// norint pradėti operaciją
db.beginTransaction ();

// baigti operaciją
db.endTransaction ();

Taip pat galbūt norėsite patikrinti, ar prieš imantis operacijos nebuvo išimčių, tada įrašykite klaidą, jei iškilo problema. Tai taip pat lengva „Android“.

bandyti {
db.beginTransaction ();

/ * Daryk daiktus kilpoje. * /

db.setTransactionSuccessful (); // Tai įvykdo sandorį, jei nebuvo jokių išimčių

} sugauti (e išimtis) {
Prisijungti.w ("Išimtis:", e);
} pagaliau {
db.endTransaction ();
}

Paruoškite ir surišite

Paskutiniame pavyzdyje SQL teiginys buvo iš naujo sukurtas vykdant kiekvieną kilpą. Tai reiškia, kad ją taip pat kaskart analizuodavo „SQLite“. Šis analizės procesas turi tam tikrų skaičiavimo pridėtinių verčių, sulėtindamas veiksmus su kiekviena iteracija.

Galite pagreitinti veiksmus, paruošdami SQL teiginį už linijos ribų, tada įrišdami duomenis į jį kiekvieną kartą, kai jį naudosite.

/ * prieš pradedant operaciją * /
sprintf (sSQL, "ĮTERPTI Į VARDŲ VERTES (NULL, @FirstName, @LastName)");
„sqlite3_prepare_v2“ (db, sSQL, BUFFER_SIZE), &stmt, &uodega);

„sqlite3_exec“ (db, "PRADĖTI SANDORIUS", NULL, NULL, &sErrMsg);

pFile = fopen (FILE_OF_NAMES,"r");
while (! feof (pFile)) {

„fgets“ („sInputBuf“, „BUFFER_SIZE“, „pFile“);

„sFirstName = strtok“ („sInputBuf“, "t");
sLastName = strtok (NULL, "t");

„sqlite3_bind_text“ („stmt“, 1, „sFirstName“, -1, „SQLITE_STATIC“);
„sqlite3_bind_text“ („stmt“, 2, „sLastName“, -1, „SQLITE_STATIC“);

sqlite3_step (stmt);

„sqlite3_clear_bindings“ (stmt);
sqlite3_reset (stmt);

n ++;
}
fklose (pFile);
„sqlite3_exec“ (db, "Baigti sandorį", NULL, NULL, &sErrMsg);
„sqlite3_close“ (db);

Ši strategija taip pat gali būti naudojama už ciklų ribų. Jei turite užklausą funkcijos viduje, galite ją vieną kartą paruošti ir susieti kiekvieną kartą, kai ji naudojama.

Parengti pareiškimai „Android“

„Android SQLite“ API suteikia „SQLiteStatement“ klasę, kaip lengvai tai padaryti.

// parašyti užklausą, su? reikšmėms įterpti
Styginių sql = "ĮTERPTI Į VARDUS VERTĖS (?,?)";

// surašykite pareiškimą
„SQLiteStatement“ pareiškimas = db.compileStatement (sql);

/ ** ciklas per įrašus ** /

/ ** gaukite vardus iš failo ir priskirkite vardams ir pavardėms ** /

// įpareigoti
pareiškimas.bindString (1, vardas);
pareiškimas.bindString (2, pavardė);

// vykd
Ilga eilutė_id = pareiškimas.executeInsert ();

Nesinchronizuokite prie disko po kiekvieno įterpimo

SQLite, pagal numatytuosius nustatymus, laukia, kol OS užrašys į diską, išleidus kiekvieną iš šių įdėklų. Šią pauzę galite išjungti naudodami paprastą komandą.

„sqlite3_exec“ (db, "PRAGMA sinchroninis = IŠJ", NULL, NULL, &sErrMsg);

Įdėkite tai atidarę ryšį su duomenų baze, bet prieš pradėdami operaciją. Taip pat turėtumėte žinoti, kad tai gali sukelti duomenų bazės sugadinimą avarijos ar elektros energijos tiekimo nutraukimo atveju. Taigi norėsite pasverti padidėjusį greitį ir įvertinti bet kokią galimą riziką.

Laikykite „Rollback Journal“ atmintyje

Jei jūs jau pavojingai gyvenate su „PRAGMA synchronous = OFF“ ir bandote išspausti visas papildomas milisekundės, galite taip pat išsaugoti atstatymo žurnalą atmintyje, o ne išsaugoti jį diske. Kartu su ankstesniu optimizavimu tai yra šiek tiek rizikinga.

„sqlite3_exec“ (db, "PRAGMA journal_mode = ATMINTIS", NULL, NULL, &sErrMsg);

Taip pat galite nustatyti journal_mode kaip OFF, jei norite laimėti greičio varžybas ar pan. (Tai nerekomenduojama naudoti realiame gyvenime.)

„Android“ skirtas žurnalo režimo įspėjimas

„SQLite“ žurnalo režimas yra valdomas naudojant „Android“ metodą „enableWriteAheadLogging ()“. Taigi, kaip rašoma neapdorotų SQL komandų vykdymo dokumentuose:

Nenustatykite „Journal_mode“ naudodami "PRAGMA žurnalas_modelis" pareiškimas, jei jūsų programa naudoja „enableWriteAheadLogging“ ().

Rodyk tik tada, kai tau to tikrai reikia

Naivūs duomenų bazių kūrėjai mėgsta kurti daugybę indeksų, kad „paspartintų reikalus“. Bet tai padaryti atsitiktinai arba indeksuoti pažodžiui viskas gali būti nenaudinga. Indeksuojant lentelės turinį pagal tam tikrą eilutę, skaitymas vyksta greičiau, o rašymas vyksta lėčiau. Ir tai tik padaro spartesnį užklausų, kurios ieškomos pagal tą stulpelį, skaitymą.

Taigi, jei vartotojai niekada neieškos lentelės turinio pagal tam tikrą stulpelį, neindeksuokite jo. Be to, jei tikėtina, kad vartotojai tik nedažnai ieško pagal tam tikrą stulpelį, neindeksuokite jo. Net jei jie greičiausiai ieškos dažnai, vis tiek turite pagalvoti, ar lentelė bus parašyta, ar ieškoma iš jos dažniau. Jei jis bus parašytas dažniau nei ieškoma, arba jei rašymo greitis yra ypač svarbus, neindeksuokite.

Dažnai šiuos poreikius diktuoja taikymo rūšis. „SQLite“ nėra dažnai naudojamas didelėms duomenų saugykloms, kuriose reikia palaikyti įvairiausias operacijas. Pvz., Jei jis naudojamas kaip programos failo tipas, tikriausiai svarbiau vartotojo galimybė greitai išsaugoti projektą dirbant, nei galimybė kuo greičiau ieškoti darbinio dokumento turinio. Kita vertus, duomenų saugojimo programa, turinti rankinius vienkartinius atnaujinimus (pvz., Kontaktų katalogą ar darbų sąrašą) tikriausiai gali būti šiek tiek lėtesnė, tačiau turėtų palaikyti labai greitą paiešką.

Rodyklė po masinio įdėjimo

Kai sukursite rodyklę ant stalo, kiekvienas įterpimas užtruks laiko naujo turinio indeksavimui. Jei jūsų lentelė bus inicijuota dideliu masinių duomenų įterpimu (galbūt pirmą kartą išsaugojant naują projektą ar dokumentą arba importuojant naujo vartotojo duomenis), galite pagreitinti tą pirmąjį didelį įterpimą laukdami, kol bus sukurta rodyklė. kol po įdėklo.

Kiti PRAGMA nustatymai

Yra keletas PRAGMA parametrų, kurie gali padėti pagerinti jūsų „SQLite“ našumą.

Talpyklos dydis

Kaip trumpai minėta aukščiau, gali reikėti padidinti savo talpyklos dydį. Didelės operacijos bus pagreitintos tik tuo atveju, jei visą operaciją bus galima išsaugoti talpykloje.

Talpykloje naudojama atmintis paskirstoma tada, kai jos reikia, todėl nėra jokios priežasties ją nustatyti per aukštai. Taip pat galite dinamiškai reguliuoti – pakeldami jį, kad optimizuotumėte tam tikras užklausas, ir tada sumažinkite, kai nereikia.

„sqlite3_exec“ (db, "PRAGMA talpyklos dydis = 100000", NULL, NULL, &sErrMsg);

Laikinas stalo saugojimas

Galite nurodyti „SQLite“ saugoti laikinas lenteles atmintyje. Tai paspartins daugelį skaitymo operacijų, kurios priklauso nuo laikinų lentelių, indeksų ir rodinių.

„sqlite3_exec“ (db, "PRAGMA temp_store = ATMINTIS", NULL, NULL, &sErrMsg);

„Android“ ir „Pragma“ nustatymai

Jei norite vykdyti neapdorotą SQL iš savo SQL duomenų bazės, galite naudoti „ExeSQL ()“ metodą. Tai yra tiesiausias būdas pakeisti bet kurį iš PRAGMA nustatymų. Tačiau kai kuriuos iš jų (pvz., Aukščiau paminėtą „Journal_mode“) valdo kitos klasės arba pagalbininkai API.

Greitesnės užklausos – filtruokite greičiau

Jei darote užklausą remdamiesi keliais kriterijais, dažnai galite ją pagreitinti, pertvarkydami, kaip jūsų kriterijai yra išdėstyti. Jei pirmoji WHERE išlyga pateikia mažiausią rezultatų skaičių, kiekvienoje paskesnėje pastraipoje bus mažiau nagrinėjamų punktų.

Užklausoje, kurioje yra daug parametrų, pabandykite eksperimentuoti su keliais skirtingais permutacijomis, kad pamatytumėte, kuris iš jų turi geriausią vidutinį greitį..

Didelės raidės indeksai LIKE

LIKE sąlyga tekstui lyginti yra maža ir mažoji raidė. Pagal numatytuosius indeksus didžiosios ir mažosios raidės yra svarbios. Jei vienintelės užklausos, kurias optimizuoja jūsų indeksai, yra LIKE užklausos, galite sutaupyti laiko intarpams ir užklausoms, padarydami indekso nejautrų.

CREATE INDEX sLastName NAME (PAGRINDINĖ SUDARYTI NOCASE);

Jei įmanoma, naudokite naujausią versiją

Kiekvienoje pagrindinėje „SQLite“ versijoje yra našumo patobulinimų. Kai kurie leidimai smarkiai padidino greitį. Taigi, jei naudojate nedidelę kelių metų senumo versiją (arba, dar blogiau, vis dar naudojate v2), lengviausias kelias į greitesnį vykdymą yra paprasčiausias atnaujinimas.

Nekurkite naujos duomenų bazės

Tai yra didelis mąstymo pokytis žmonėms, atvykstantiems iš kitų RDBMS sistemų.

Apsvarstykite atvejį, kai SQLite naudojamas kaip programos failo formatas. Kiekvieną kartą, kai pirmą kartą išsaugote naują projektą (failą) programoje, reikalingas naujas duomenų bazės egzempliorius.

Galite sukurti naują duomenų bazę ir vykdyti SQL teiginių seriją, kad pridėtumėte atitinkamas lenteles ir rodykles. Tai jūs norėtumėte padaryti, jei kurtumėte dislokuotiną programą su (pavyzdžiui) PostgreSQL – parašytumėte kodą, kad nustatytumėte duomenų bazę, ir paleistumėte ją įdiegdami.

Tačiau yra greitesnis būdas.

Kadangi „SQLite“ duomenų bazė yra atskiras failas, klijuoti duomenų bazę yra gana nereikšminga – tai tiesiog failo kopija. Tai reiškia, kad paprastai nebūtina kurti naujos duomenų bazės ir vykdyti visų reikalingų SQL teiginių. Paprastai galite tiesiog pasidaryti kopiją.

„Android“ naudodami „SQLite Asset Helper“ galite valdyti duomenų bazes kaip išteklius tai darydami.

Apsvarstykite galimybę denormalizuoti

Jei turite patirties su reliacinėmis duomenų bazių sistemomis, jums gali būti labai rūpi normalizuoti savo duomenis. Tai yra daug daugiau nei tai, bet duomenų normalizavimo esmė yra: vienas tiesos šaltinis.

Normalizuotoje reliacinėje duomenų bazėje bet kokie duomenys, nesvarbu, kaip nereikšmingi, pateikiami tiksliai vieną kartą. Taigi, pavyzdžiui, knygą reprezentuojantis įrašas gali būti nuoroda į autorių reprezentuojantį įrašą, tačiau tai tikrai nenurodytų autoriaus vardo tiesiogiai.

Tai taupo vietą ir yra elegantiškesnė. Be to, skaitymas iš duomenų bazės reikalauja daug daugiau laiko. Jei norite rasti visas autoriaus knygas, turite ieškoti autorių lentelės, kad gautumėte ID, tada ieškoti knygų lentelės ir surinkti įrašus.

Galite pagreitinti tokio pobūdžio skaitymą, kopijuodami autoriaus vardą visuose knygos įrašuose. Tai pagerina našumą, tačiau pakenčia normalizavimą. Be neelegancijos, tai turi du galimus trūkumus:

  • Programos logika tampa atsakinga už duomenų vientisumo (ty teisingumo ar tikslumo) palaikymą.
  • Duomenų bazė turės būti didesnė, kad būtų galima saugoti tą patį informacijos kiekį.

Denormalizavimas SQLite yra ypač geras

Visi šie rūpesčiai ir kompromisai kyla dirbant su bet kuria RDBMS sistema, o ne tik su SQLite. Tačiau „SQLite“ yra keletas potencialiai lengvinančių veiksnių, dėl kurių duomenų denormalizavimas tampa mažiau problematiškas ir naudingesnis.

  • Paprastai „SQLite“ programa turės mažiau sudėtingą duomenų modelį (schemą) nei labai didelė programa, kuriai reikia duomenų bazės serverio. Tai daro sudėtingesnį programos, reikalingos denormalizuotiems duomenims paremti, sudėtingumą.
  • Duomenų rinkiniai, kuriuos palaiko „SQLite“ duomenų bazės, paprastai yra mažesni nei tie, kurie saugomi kitose duomenų bazių sistemose. Tai reiškia, kad padidinti dubliuotų duomenų dydį nėra taip sudėtinga. Be to, daugumos „SQLite“ programų (vietinės failų saugyklos) mastu papildomo dydžio kaina yra nereikšminga.
  • Skirtingai nuo didelių duomenų bazių serverių (ypač tų, kuriuos prižiūri organizacijos), mažai tikėtina, kad antroji programa bandys prisijungti prie jūsų programos sukurtų SQLite duomenų bazės failų. Todėl jums nereikia saugotis atsitiktinio duomenų sugadinimo ir probleminės komandos dinamikos.
  • Panašiai, kadangi „SQLite“ paprastai naudojama kaip įterptinė duomenų bazė, programa ir duomenų bazės struktūra dažnai yra glaudžiai susiję. Tai reiškia, kad duomenų tvarkymo vientisumas programos viduje yra žemesnis nei paprastai, kai duomenų bazė ir programa yra fiziškai laisvai sujungtos, tačiau realybėje yra labai susijusios..
  • Galiausiai, kai kurie normalizacijos palaikymo efektyvumo patobulinimai, galimi kitose duomenų bazių sistemose, pavyzdžiui, materializuoti rodiniai, nėra SQLite.

Dėl šių priežasčių SQLite yra daug labiau įprasta atlikti eksploatacinių savybių denormalizavimą nei su kitomis reliacinėmis duomenų bazėmis.

Santrauka

Šie patarimai, kaip optimizuoti SQLite našumą, yra būtent tokie. Tai nėra tikslus planas, kurio reikia laikytis, ir jūs nepagreitinsite savo „SQLite“ programos, tiesiog pridėdami kiekvieną kodą iš šio sąrašo į savo kodą. Tai idėjos, kurios gali padėti, jei jos bus tinkamai panaudotos. Taigi pagalvokite apie savo paraišką ir sužinokite, ar kuri nors iš jų galėtų padėti. Ir išbandyti. Prieš pradėdami greitai naudoti, turite išsiaiškinti, dėl ko jūsų programa lėtėja.

Tolesni skaitymai ir šaltiniai

Turime daugiau vadovų, vadovėlių ir infografijų, susijusių su kodavimu ir plėtra:

  • SQL ištekliai: mūsų bendras SQL šaltinis, kuris yra būtinas visiems reliacinių duomenų bazių kūrėjams.
  • „MySQL“ įvadas ir ištekliai: dar viena labai populiari duomenų bazių sistema.
  • „PostgreSQL“ įvadas ir šaltiniai: pati populiari duomenų bazių sistema, „SQLite“ iš dalies tuo pagrįsta.

Galutinis žiniatinklio prieglobos vadovas

Peržiūrėkite mūsų svarbiausią žiniatinklio prieglobos vadovą. Tai paaiškins viską, ką turite žinoti, kad galėtumėte priimti pagrįstą sprendimą.

Galutinis žiniatinklio prieglobos vadovas
Galutinis žiniatinklio prieglobos vadovas

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map