The above answer (by Adrian Carneiro) is fantastic, and works unless the table uses a different field as primary key and does NOT have a key for 'id'.
Given a table with a primary key of userid :-
MariaDB [unixua]> select userid, uid from accounts;
+---------+----------+
| userid | uid |
+---------+----------+
| acc0001 | 89814678 |
| acc0002 | 38000474 |
| acc0005 | 38000475 |
| acc0017 | 38000478 |
+---------+----------+
4 rows in set (0.00 sec)
We'd expect the lowest free number to be 38000476.
MariaDB [unixua]> SELECT t1.uid +1 FROM accounts t1
LEFT JOIN accounts t2 ON (t1.uid +1 = t2.uid)
WHERE t2.uid IS NULL AND t1.uid>38000474 LIMIT 1;
+-----------+
| t1.uid +1 |
+-----------+
| 89814679 |
+-----------+
1 row in set (0.00 sec)
But, because MySQL / MariaDB is selecting them in primary key order, this fails, and gives the next highest after "acc001".
By adding a key to the uid column and only performing the SELECT on the "uid" column, MySQL/MariaDB will use the index to retrieve data (instead of reading the table). Since the index is "ordered", the result is different :-
MariaDB [unixua]> alter table accounts add unique index (uid);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [unixua]> SELECT t1.uid +1 FROM accounts t1
LEFT JOIN accounts t2 ON (t1.uid +1 = t2.uid)
WHERE t2.uid IS NULL AND t1.uid>38000474 LIMIT 1;
+-----------+
| t1.uid +1 |
+-----------+
| 38000476 |
+-----------+
1 row in set (0.00 sec)
Make sure your table has a key for the Customer ID field (and that customer ID field is numeric).
This works because the optimiser can retrieve all necessary data for the select from the index (aka accounts.myi, not accounts.myd), not the table data.