I haven't done it on databases, but I managed to write my own listbox component that can do live search.
The performance is good, you will start to feel the sluggishness when it reaches 300k of items. But still acceptable until 500k, tested on old Core 2 Duo machines. The key for the optimization is, you need to know: string operations are expensive. My component internally uses 2 list containers for caching the search result. These containers are dynamic array of longint. There is no string moving, copying or deleting. All those operations are performed on the list containers, which actually are the index that points to the 'real' string list. You can see demo on the attached video.
Now back to your question. In your case, how to speed it up.
Load the primary key and the searchable fields in to memory. Don't reload the data from database every time user doing keypress, but perform those operations on computer's memory. Nowadays a 8 GB DDR costs less than $3. And avoid copying, moving, deleting nor trimming strings because string operation are expensive.