Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many rows can an SQLite table hold before queries become time comsuming

Tags:

sqlite

I'm setting up a simple SQLite database to hold sensor readings. The tables will look something like this:

sensors  
 - id (pk) 
 - name  
 - description
 - units  

sensor_readings  
 - id (pk)  
 - sensor_id (fk to sensors)  
 - value (actual sensor value stored here)
 - time (date/time the sensor sample was taken)

The application will be capturing about 100,000 sensor readings per month from about 30 different sensors, and I'd like to keep all sensor readings in the DB as long as possible.

Most queries will be in the form

SELECT * FROM sensor_readings WHERE sensor_id = x AND time > y AND time < z

This query will usually return about 100-1000 results.

So the question is, how big can the sensor_readings table get before the above query becomes too time consuming (more than a couple seconds on a standard PC).

I know that one fix might be to create a separate sensor_readings table for each sensor, but I'd like to avoid this if it is unnecessary. Are there any other ways to optimize this DB schema?

like image 772
bengineerd Avatar asked Oct 09 '08 06:10

bengineerd


People also ask

How many rows can a SQLite table handle?

The theoretical maximum number of rows in a table is 264 (18446744073709551616 or about 1.8e+19). This limit is unreachable since the maximum database size of 281 terabytes will be reached first.

How long does a SQLite query take?

Query one takes about 30ms, but 150ms to fetch the data from the database. Query two takes about 3ms -this is the one I therefore prefer-, but also takes 170ms to fetch the data. SELECT ( SELECT prod2. value FROM product_to_value, product_to_value as prod2, features, featurevalues WHERE product_to_value.

How much data is too much for SQLite?

SQLite database files have a maximum size of about 140 TB. On a phone, the size of the storage (a few GB) will limit your database file size, while the memory size will limit how much data you can retrieve from a query. Furthermore, Android cursors have a limit of 1 MB for the results.


4 Answers

If you're going to be using time in the queries, it's worthwhile adding an index to it. That would be the only optimization I would suggest based on your information.

100,000 insertions per month equates to about 2.3 per minute so another index won't be too onerous and it will speed up your queries. I'm assuming that's 100,000 insertions across all 30 sensors, not 100,000 for each sensor but, even if I'm mistaken, 70 insertions per minute should still be okay.

If performance does become an issue, you have the option to offload older data to a historical table (say, sensor_readings_old) and only do your queries on the non-historical table (sensor_readings).

Then you at least have all the data available without affecting the normal queries. If you really want to get at the older data, you can do so but you'll be aware that the queries for that may take a while longer.

like image 189
paxdiablo Avatar answered Jan 02 '23 23:01

paxdiablo


Are you setting indexes properly? Besides that and reading http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html, the only answer is 'you'll have to measure yourself' - especially since this will be heavily dependent on the hardware and on whether you're using an in-memory database or on disk, and on if you wrap inserts in transactions or not.

That being said, I've hit noticeable delays after a couple of tens of thousands of rows, but that was absolutely non-optimized - from reading a bit I get the impression that there are people with 100's of thousands of rows with proper indexes etc. who have no problems at all.

like image 32
Roel Avatar answered Jan 02 '23 23:01

Roel


SQLite now supports R-tree indexes ( http://www.sqlite.org/rtree.html ), ideal if you intend to do a lot of time range queries.

Tom

like image 27
gobansaor Avatar answered Jan 02 '23 23:01

gobansaor


I know I am coming to this late, but I thought this might be helpful for anyone that comes looking at this question later:

SQLite tends to be relatively fast on reading as long as it is only serving a single application/user at a time. Concurrency and blocking can become issues with multiple users or applications accessing it at a single time and more robust databases like MS SQL Server tend to work better in a high concurrency environment.

As others have said, I would definitely index the table if you are concerned about the speed of read queries. For your particular case, I would probably create one index that included both id and time.

You may also want to pay attention to the write speed. Insertion can be fast, but commits are slow, so you probably want to batch many insertions together into one transaction before hitting commit. This is discussed here: http://www.sqlite.org/faq.html#q19

like image 44
TimothyAWiseman Avatar answered Jan 03 '23 01:01

TimothyAWiseman