I have a large SQLite database for my application (around 100MB). This database is read only and never written into. The performance of working with the database is decent, since I made sure that most of the queries have indexes backing them up. However I would like to speed it up further by caching the entire database into RAM to avoid disk access.
Is this possible and if so how can I do it?
A database file is a file, so you can just read it to put it into the OS's file cache. (And if the OS decides to throw the data out again, then it might have a reason for it …)
For an on-disk database, SQLite needs to check if some other process has made changes. To avoid that, you can use
PRAGMA locking_mode = EXCLUSIVE. However, the difference probably isn't measurable.
Related
I have a rather large SQLite database (~20 mb) I need to access from my Android Xamarin-Forms app.
Everything online I've read says you can read the database by copying it to the filesystem first. For example, this question. However, won't that mean the large database is duplicated, wasting users' precious space (and nearly doubling the footprint of my app)?
There must be a way to read the SQLite database directly from the assets, or use some other method to bundle the database with my app that won't waste so much space. But how can I do this?
You don't want to use it from assets, even if you could, because assets is a compressed read only file, part of your installation. You can't write updates into it, which kills 90% of database use. And its inefficient for reading as its zipped up. So you really do need to copy it. If you're worried about disk space, consider downloading it from the web rather than keeping it in your apk.
I'm asking for a piece of advice. Currently, we are developing android client for out service. Service produces like a lot of dynamic information, and it must be stored on users phone so it can be accessed without connection to the net. On iOS client we achieved this using restKit. On android I found that there is no tool like restKit. So there are 2 options - use sqlite db or cache last json response. I want to use sqlite db, but our android developer sad that it's not stable and slow. Is he right? What practice is better?
The second question is that I found a sqlite editor app, which allows to edit sqlite databases on phone. Is there any way to avoid this?
You can use SQLite because SQLite is capable of being extremely fast. If you are seeing speeds slower than other DB systems such as MySQL or PostGres, then you are not utilizing SQLite to its full potential. Optimizing for speed appears to be the second priority of D. Richard Hipp, the author and maintainer of SQLite. The first is data integrity and verifiability.
The first thing you should know is that most of the time spent by SQLite (and most other DB systems) is on disk access, which is slow compared to memory operations. So the key to optimizing SQLite is to minimize the amount of disk access required. This requires some understanding of when SQLite is accessing information on disk, and why. Because operating systems generally cache open disk files in memory, a carefully tuned use of SQLite can approach the speed of a pure in-memory database.
If you are new to optimization, you must know that the only reliable way to optimize for speed is to measure where time is being spent. Unless you are already familiar with doing this for SQLite, you will often guess wrong. Use quantitative tests on representative examples whenever possible. Unfortunately, reproducibly measuring performance on an application that does disk access isn't trivial.
However it is difficult to use cache no doubt cache is fast but its not for large data and data cannot stored on cache for long time. So if you want that user will use your app offline then you should place your data on SQLite in an optimized way.
Hope this will help you.
No according to experience SQLite is the most reliable database to use in android device itself. It doesn't have separate server process and it directly read/right to single disk file.
This link will provide more information
I have a huge database and I want my application to work with it as soon as possible. I'm using android so resources are more restricted. I know that its not a good idea to storage huge data in the sqlite database, but I need this.
Each database contain only ONE table and I use it READ only.
What advice can you give me to optimize databases as much as possible. I've already read this post, and except the PRAGMA commands what else can I use?
Maybe there are some special types of the tables which are restricted for read only queries, but principally faster then ordinary table types?
As long as your database fits on the device, there is no problem with that; you'll just have less space for other apps.
There is no special table type. However, if you have queries that use only a subset of a table's columns, and if you have enough space left, consider adding one or more covering indexes.
Being read-only allows the database to be optimized on the desktop, before you deploy it:
set page size, etc.;
create useful indexes;
ANALYZE
VACUUM
In your app, you might experiment with increasing the page cache size, but if your working set is larger than free memory, that won't help anyway. In any case, random reads from flash are fast, so that would not be much of a problem.
Huge is relative. But ultimately a device is constrained on storage and memory. So assuming that huge is beyond the typical constraints of a device, you have a few options.
The first option is to store your huge dataset in the cloud and the connected device can offer views into that data by offering cloud services with something like RESTful APIs from the coud to proffer the data to the device. If the device and app rely on always being connected, you don't need as much local storage unless you want to cache data.
Another approach is an occasionally connected device (sometimes offline) where you pull down a slice of the most relevant data to work on to the device. In that model, yo can work offline and push/pull back to the cloud. In this model, sqlite is the storage mechanism to hold that slice of relevant data.
EDIT based on comments:
Concerning optimizing what you have on the device, see the optimization FAQ here:
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
(in rough order of effectiveness)
Use an in-memory database
Use BEGIN TRANSACTION and END TRANSACTION
Use indexes Use PRAGMA cache_size
Use PRAGMA synchronous=OFF
Compact the database
Replace the memory allocation library
Use PRAGMA count_changes=OFF
Maybe I'm stating the obvious but you should probably just open it with the SQLITE_OPEN_READONLY flag to sqlite3_open: I think that SQLite will take advantage of this fact and optimize the behaviour of the engine.
Note that all normal SQL(ite) optimization tips still apply (e.g. VACUUMing to finalize the database, setting the correct page size at database creation, proper indexes and so on...)
In addition, if you have multiple threads accessing the database in your application, you may want to try out also the SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_SHAREDCACHE flags (they require sqlite3_open_v2, though)
Also you need journalling switch off, because data not change http://www.sqlite.org/pragma.html#pragma_journal_mode
PRAGMA journal_mode=OFF
In my application, I'm retrieving content from the database very often. So I'm likely to access data from database when it is required. For example, even within an activity I'll open and close the database 3 to 4 times. Is this enough to cause performance to suffer?
This would really depend on the amount of data you are reading and how complicated the queries are. Personally I wouldn't worry about unless you can notice the performance issue, why fix a problem that doesn't exist. That said if you are noticing performance problems and think the database may be the cause you can try the following:
Cache database reads so they only have to be done when something is updated.
Wrap database writes in transactions so the disk writes are done all in one go.
Only read the data you need. For instance if you have a list the displays 3 out of the 20 fields only read the 3 fields you need.
I am developing an application that periodically sends information to an external server. I make a local copy of the data being sent, for backup purposes.
What is the best option to store the data in terms of saving battery life? Each data submission is a serialized object (the class has 5 fields, including a date, numbers and strings) of about 5K-10K.
Any other idea?
I don't believe it matters whether you use SQLite or a File, because the SQLite db is simply a file on the system (stored in /data/data/<your_package>/databases/). You'll need to commit to the db at the right times, just as much as you would need to save a file to the hard drive at the right times. In other words, one way or the other you can use just as many hard drive writes.
I think that what you choose depends more on what sort of data you are saving. If you need the powers that having a db can bestow (such as querying), then by all means use SQLite. However, if you don't need a db, or you've got data that varies wildly (and can't be easily setup in a relational database) then I'd go with files.
What I can tell you for sure is that you should not use serialization for saving a file, if that is the route you choose to go. Android serialization is slow, slow, slow and creates large files. It is much better to either write your own XML or JSON format for performance reasons.
I have no idea in terms of battery life directly but one criteria would be which is easier to manage? Fewer operations to manage the data would mean fewer CPU cycles and in turn longer battery life.
I would say the SQLite option is easier. You can put a date column in the SQLite table which stores your data which makes removing old submissions which you don't need any more very easy - and all handled via the native SQL library. Managing a whole load of file - or worse a single file - with your own Java code would be much more work.
Additionally, you can write data the to database and just forget about it until you need to read it again. If you're storing data in files, you'll need to work out when you should be reading and writing files in terms on the Android application life cycle. If you're worried about battery you probably wouldn't want to write files more often than you should, and cache data in memory, but you'd need to make sure you didn't lose any data when your app is Paused or Destroyed. In my opinion it's much easier to use an SQLite database and not worry about any of this.
Is your application multi-threaded? If you have multiple threads accessing the data store then I would go with SQLite. Let SQLite worry about locking issues.