Skip to content
Ahmed Hammad BlogA small bird flying along a dashed path

Using UUID as a Primary Key

I am developing a personal finance application on mobile and web. Data should be synced two ways between the mobile app and the web application.

The data schema is:

As for compatibility with server database, I added user id to all tables and a little User table with just our user ID, name and email.

I am using sample data with about 4500 transactions. The total size of the SQLite files is 324K Byte.

I am using the auto-increment primary key that is managed by SQLite. As I wanted to implement a sync feature between mobile apps and web app. I thought changing autoincrement id with UUID is a good idea to be able to sync data in two ways.

I did some research, and I found two options:

For the sake of saving space on the mobile device, I decided to use BLOB. But I worried about performance, so I did some research.

I read multiple blogs, articles, and SQLite reference and found that there is no negative performance impact on using UUID either in binary or text. But of course, size will be much bigger especially in case of using the 36 bytes text-based UUID.

Before doing any changes. This is my performance numbers of the main APIs per one call to compute balances that are being displayed in the application dashboard.

  1 ║ Calculations time   │ 634  │ milliseconds
  2 ║ Asset Accounts      │ 358  │ milliseconds
  3 ║ Liability Accounts  │ 70   │ milliseconds
  4 ║ Expense Accounts    │ 68   │ milliseconds
  5 ║ Income Accounts     │ 67   │ milliseconds
  6 ║ Other Accounts      │ 69   │ milliseconds
  7 ║ Total               │ 1266 │ milliseconds

Rows from 1 to 6 is an SQLite fetch from database and balance calculations. I did timing measurements for display refresh and found it very fast. So the bottleneck is in SQL data access.

As the whole database is 324K, I expect SQLite to load most of it to memory to give the best performance.

Then I spent an extensive effort to change all Primary Keys and Foreign Keys to be BLOB 16 bytes and migrate data. I notice that:

The database grew to 807 KB.
The performance almost degrades immediately as follows:

  1 ║ Totals Calculations │ 1295 │ milliseconds
  2 ║ Asset Accounts      │ 670  │ milliseconds
  3 ║ Liability Accounts  │ 120  │ milliseconds
  4 ║ Expense Accounts    │ 147  │ milliseconds
  5 ║ Income Accounts     │ 147  │ milliseconds
  6 ║ Other Accounts      │ 98   │ milliseconds
  7 ║ Total               │ 2477 │ milliseconds

This is almost double the time!

The first thing to think of to improve DB performance is adding indexes. So, I added indexes gradually and measured performance after each index. In the end, I added 4 indexes to fields that are used in the query where part and order by parts. I measured again and found these performance numbers.

  1 ║ Totals Calculations │ 1078 │ milliseconds
  2 ║ Asset Accounts      │ 639  │ milliseconds
  3 ║ Liability Accounts  │ 111  │ milliseconds
  4 ║ Expense Accounts    │ 123  │ milliseconds
  5 ║ Income Accounts     │ 141  │ milliseconds
  6 ║ Other Accounts      │ 97   │ milliseconds
  7 ║ Total               │ 2189 │ milliseconds

The performance improved just by 188 milliseconds! While DB size jumped up to 1.4 Mega. Remember it was initially about 300KB.

I do expect database size to increase by adding indexes, but how performance is not improving at all!!

Lessons Learned and Ideas:

Conclusions:

Useful Links:

From ahm507.blogspot.com