Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage
Forum Updated to NodeBB v4.3 + New Features

QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage

Scheduled Pinned Locked Moved Unsolved General and Desktop
18 Posts 4 Posters 1.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by mbruel
    #1

    Hi,
    In my app, I'm getting a flat SQLite database, that I want to present in a View. I didn't decide yet if it will be a TreeView or ListView.
    Well it will be easier with the example. The app is ClementineRemote, the DB contains songs with a title, an artist, an album, a filename...

    I wish to have a text search feature that would search on all the fields I've given above.
    I've no clue, which tech would be faster between a QSortFilterProxyModel with its filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) or using SQL, especially with FTS.

    The Android-Remote dev in Java made the choice of SQL with a tweak of the database to create a virtual FTS3 table and adding indexes. (cf here)

    I'm hesitating to load everything in a tree Model but I'm wondering what will be the perf. The app will run on both desktop and mobiles.
    In term of volume, I imagine, it could be between 1k and 100k entries. (I've 40k)
    Let's say we got 100 chars per entry, it mean 100kB*200 = 20MB of memory which is fine.
    I'm more concerned on the search part using a regexp on different roles for every entries...
    What do you think?

    I've never looked into FTS algorithm and performance but the numbers I've seen are quite impressive compare to the regular search using a LIKE. The problem is that it is looking for complete words and I'd rather not have this limitation.
    But still, would QSortFilterProxyModel be faster than SQLite (or another DB) for text search?
    Is there some benchmarks about this?
    How many entries can support QSortFilterProxyModel? After which number you would stop using it and turn to SQL DB?

    JonBJ 1 Reply Last reply
    0
    • mbruelM mbruel

      Hi,
      In my app, I'm getting a flat SQLite database, that I want to present in a View. I didn't decide yet if it will be a TreeView or ListView.
      Well it will be easier with the example. The app is ClementineRemote, the DB contains songs with a title, an artist, an album, a filename...

      I wish to have a text search feature that would search on all the fields I've given above.
      I've no clue, which tech would be faster between a QSortFilterProxyModel with its filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) or using SQL, especially with FTS.

      The Android-Remote dev in Java made the choice of SQL with a tweak of the database to create a virtual FTS3 table and adding indexes. (cf here)

      I'm hesitating to load everything in a tree Model but I'm wondering what will be the perf. The app will run on both desktop and mobiles.
      In term of volume, I imagine, it could be between 1k and 100k entries. (I've 40k)
      Let's say we got 100 chars per entry, it mean 100kB*200 = 20MB of memory which is fine.
      I'm more concerned on the search part using a regexp on different roles for every entries...
      What do you think?

      I've never looked into FTS algorithm and performance but the numbers I've seen are quite impressive compare to the regular search using a LIKE. The problem is that it is looking for complete words and I'd rather not have this limitation.
      But still, would QSortFilterProxyModel be faster than SQLite (or another DB) for text search?
      Is there some benchmarks about this?
      How many entries can support QSortFilterProxyModel? After which number you would stop using it and turn to SQL DB?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @mbruel
      I don't use SQLite. But I used Full Text Search on MS SQL Server. And, as you'd expect, it was about a squillion times faster than a non-FTS LIKE predicate. Of course, it had to maintain FTS tables for every word in the data. T-SQL CONTAINS() can search for left-hand side match (CONTAINS (column, '"text*"')), I don't know about SQLite.

      1 Reply Last reply
      0
      • mbruelM Offline
        mbruelM Offline
        mbruel
        wrote on last edited by
        #3

        @JonB and after what point (number of items, size of the text) would you recommand SQL rather QSortFilterProxyModel?
        Are there benchmarks on the subject?
        Something to have in mind, is that if I use SQL, I need to repopulate the model each time I do a search. Does it worth it?

        JonBJ 1 Reply Last reply
        0
        • mbruelM mbruel

          @JonB and after what point (number of items, size of the text) would you recommand SQL rather QSortFilterProxyModel?
          Are there benchmarks on the subject?
          Something to have in mind, is that if I use SQL, I need to repopulate the model each time I do a search. Does it worth it?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @mbruel
          Nobody can answer what the performance would be like of SQLite, with or without FTS, compared to Qt code without trying in desired situation. It's like asking how long is a piece of string.

          I don't actually think your issue is necessarily FTS vs LIKE. More to me is: I wouldn't read 40,000 records into memory and then filter them. Admittedly I use remote SQL servers where this is very significant, I don't know how that compares to SQLite with a local file, but still I'd rather give the database the opportunity to do the filtering....

          So, if I understand your situation correctly, I'd probably want to compose the SQL query with (multiple column, if that's what you want) LIKE statements, and see how it performs. Then if I were interested I'd try adding FTS (might be a bit of work) versus filterAcceptsRow(), and compare those to the LIKE to see how they compared.

          1 Reply Last reply
          1
          • mbruelM Offline
            mbruelM Offline
            mbruel
            wrote on last edited by
            #5

            @JonB
            well it seems to me we could have some general figures on the performance of QSortFilterProxyModel filtering 10k, 100k, 1M entries using a regexp text search and compare that to a database (with ot without FTS). Or at least some feedback from people having experienced both on a given situation.

            Having 40k or even 100k records in memory doesn't really scares me. It would only be loaded once and could then be faster for filtering but that is my question basically...
            I've done it on professional projects and it was reacting quite fast but it was on decent stations... my concern is that I may target mobile phones or RPI.

            It's either I go using SQL and the local SQLite db I've got (with or without FTS) OR I use a QSortFilterProxyModel. The design will be completely different. Using SQL, I'll just a need a regular QAbstractItemModel that I will clear and repopulate each time there is a search. Could this process be less smooth in term of user experience?

            JonBJ 1 Reply Last reply
            0
            • mbruelM mbruel

              @JonB
              well it seems to me we could have some general figures on the performance of QSortFilterProxyModel filtering 10k, 100k, 1M entries using a regexp text search and compare that to a database (with ot without FTS). Or at least some feedback from people having experienced both on a given situation.

              Having 40k or even 100k records in memory doesn't really scares me. It would only be loaded once and could then be faster for filtering but that is my question basically...
              I've done it on professional projects and it was reacting quite fast but it was on decent stations... my concern is that I may target mobile phones or RPI.

              It's either I go using SQL and the local SQLite db I've got (with or without FTS) OR I use a QSortFilterProxyModel. The design will be completely different. Using SQL, I'll just a need a regular QAbstractItemModel that I will clear and repopulate each time there is a search. Could this process be less smooth in term of user experience?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @mbruel said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

              well it seems to me we could have some general figures on the performance of QSortFilterProxyModel filtering 10k, 100k, 1M entries using a regexp text search and compare that to a database (with ot without FTS). Or at least some feedback from people having experienced both on a given situation.

              Best of luck for the feedback.

              It's either I go using SQL and the local SQLite db I've got (with or without FTS) OR I use a QSortFilterProxyModel. The design will be completely different. Using SQL, I'll just a need a regular QAbstractItemModel that I will clear and repopulate each time there is a search

              I don't understand. In both cases you'll want a SQL model, like QSqlQuery/TableModel. Then you may or may not want to place a QSortFilterProxyModel on top of it. In neither case will you have (just) "a regular QAbstractItemModel".

              1 Reply Last reply
              0
              • mbruelM Offline
                mbruelM Offline
                mbruel
                wrote on last edited by mbruel
                #7

                @JonB

                Best of luck for the feedback.

                haha thanks. I would have imagined that Qt could provide such things to kind of "benchmark" their Proxy mechanism... or that some people would have done it to see how it reacts under heavy load.

                I don't understand. In both cases you'll want a SQL model, like QSqlQuery/TableModel. Then you may or may not want to place a QSortFilterProxyModel on top of it. In neither case will you have (just) "a regular QAbstractItemModel".

                In the case I use a Proxy, I was thinking populating by hand ONCE a QAbstractItemModel from the whole table by iterating a single QSqlQuery.

                In the case I go SQL, I imagine to have ONE QAbstractItemModel that is used by my QML View. And I would repopulate it each time I do search query. (same way, iterating through the QSqlQuery).
                Do you think it is best to use QSqlQueryModel and change the source of the View? I'm not sure how to do that, from now I'm just accessing C++ from QML, I've not tried yet to modify QML from C++. I suppose it is possible.

                1 Reply Last reply
                0
                • mbruelM Offline
                  mbruelM Offline
                  mbruel
                  wrote on last edited by
                  #8

                  I forgot to say, in case I go with a Proxy and loading by hand a QAbstractItemModel, it's because I want to build a tree instead of keeping a flat model. (having my songs under their albums under their artists)
                  I've read we could use a Proxy to map a flat model to a tree one by implementing mapToSource and mapFromSource but it sounds hell more complicated than building the tree. Maybe I'm wrong.. don't know, I'd need to see some examples...

                  In the case of SQL, I might just keep a flat model using sequential views (first Artists, then Albums, then tracks) not sure...

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Online
                    Christian EhrlicherC Online
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @mbruel said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                    haha thanks. I would have imagined that Qt could provide such things to kind of "benchmark" their Proxy mechanism... or that some people would have done it to see how it reacts under heavy load.

                    It all depends on the data - every benchmark will be wrong for any other usecase.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    1
                    • mbruelM Offline
                      mbruelM Offline
                      mbruel
                      wrote on last edited by
                      #10

                      @Christian-Ehrlicher said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                      It all depends on the data - every benchmark will be wrong for any other usecase.

                      yes that's true, but it could give a general idea and maybe warn about bottlenecks... like 5% match (text search) on X records (10k, 100k, 1M) of text length 1000 chars for example.

                      Well, as I'm learning QML, I've chosen the Proxy way using a self populated tree Model.
                      It's working great, even on an old iPhone SE :)

                      I lost most of the time to tweak the deprecated TreeView from Controls 1.4... what a shame it is not in the v2 oO I hope it will be back with Qt6... It is definitely needed even if it is an hassle to understand how to render it (especially due to the necessary TableViewColumn....)

                      For those interested, I filter up and down the tree ProxyModel for each row in order to make the filtering decision. It works smoothly with 40k records.
                      Here is the filtering method.

                      @JonB and here is the way I populate the model from SQL. with the request being:

                      const QString ClementineRemote::sLibrarySQL =
                              "select artist, album, title, track, filename from songs order by artist, album, track, title";
                      
                      Christian EhrlicherC 1 Reply Last reply
                      0
                      • fcarneyF Offline
                        fcarneyF Offline
                        fcarney
                        wrote on last edited by
                        #11

                        Have you played with QSqlTableModel? It is based upon the abstract table model. I am going to be using this in a project and am curious if you compared its speed.

                        C++ is a perfectly valid school of magic.

                        mbruelM 1 Reply Last reply
                        0
                        • fcarneyF fcarney

                          Have you played with QSqlTableModel? It is based upon the abstract table model. I am going to be using this in a project and am curious if you compared its speed.

                          mbruelM Offline
                          mbruelM Offline
                          mbruel
                          wrote on last edited by
                          #12

                          @fcarney no I've not tried QSqlTableModel. As explained I wanted a Tree not a table.
                          alt text

                          1 Reply Last reply
                          0
                          • mbruelM mbruel

                            @Christian-Ehrlicher said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                            It all depends on the data - every benchmark will be wrong for any other usecase.

                            yes that's true, but it could give a general idea and maybe warn about bottlenecks... like 5% match (text search) on X records (10k, 100k, 1M) of text length 1000 chars for example.

                            Well, as I'm learning QML, I've chosen the Proxy way using a self populated tree Model.
                            It's working great, even on an old iPhone SE :)

                            I lost most of the time to tweak the deprecated TreeView from Controls 1.4... what a shame it is not in the v2 oO I hope it will be back with Qt6... It is definitely needed even if it is an hassle to understand how to render it (especially due to the necessary TableViewColumn....)

                            For those interested, I filter up and down the tree ProxyModel for each row in order to make the filtering decision. It works smoothly with 40k records.
                            Here is the filtering method.

                            @JonB and here is the way I populate the model from SQL. with the request being:

                            const QString ClementineRemote::sLibrarySQL =
                                    "select artist, album, title, track, filename from songs order by artist, album, track, title";
                            
                            Christian EhrlicherC Online
                            Christian EhrlicherC Online
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @mbruel said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                            ike 5% match (text search) on X records (10k, 100k, 1M) of text length 1000 chars for example.

                            How should this be possible? It depends on your implementation and your data...

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            mbruelM 1 Reply Last reply
                            0
                            • Christian EhrlicherC Christian Ehrlicher

                              @mbruel said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                              ike 5% match (text search) on X records (10k, 100k, 1M) of text length 1000 chars for example.

                              How should this be possible? It depends on your implementation and your data...

                              mbruelM Offline
                              mbruelM Offline
                              mbruel
                              wrote on last edited by
                              #14

                              @Christian-Ehrlicher it should only depend on the data. the idea would be to produce a data set of N records with length around a determined number of chars l.
                              Then you provide texts to search that would match an exact percentage p.
                              you can do that using whatever DB. Normally if you export the data set in another one or in whatever program, the output should be the same. You can thus compare the execution time. Does it make sense?

                              1 Reply Last reply
                              0
                              • Christian EhrlicherC Online
                                Christian EhrlicherC Online
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                @mbruel said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                                Does it make sense?

                                Not really - how to you compare texts is very important, also if you don't compare text but numbers and so on.
                                You can write a testcase on your own to check it.

                                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                Visit the Qt Academy at https://academy.qt.io/catalog

                                1 Reply Last reply
                                0
                                • mbruelM Offline
                                  mbruelM Offline
                                  mbruel
                                  wrote on last edited by
                                  #16

                                  @Christian-Ehrlicher the idea would have been to test comparison implementation on text only, for example a LIKE "%<text>%"
                                  but I see what you mean.
                                  I guess this kind of testing is done by companies to decide which tool/implementation to use on products where performance is critical. Myself, I don't have this need...

                                  JonBJ 1 Reply Last reply
                                  0
                                  • mbruelM mbruel

                                    @Christian-Ehrlicher the idea would have been to test comparison implementation on text only, for example a LIKE "%<text>%"
                                    but I see what you mean.
                                    I guess this kind of testing is done by companies to decide which tool/implementation to use on products where performance is critical. Myself, I don't have this need...

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by
                                    #17

                                    @mbruel said in QSortFilterProxyModel vs SQLite (with FTS3)? in term of performance and memory usage:

                                    LIKE "%<text>%"

                                    Nothing to do with your proposed timing tests. Just want to make sure you are aware: there will (should) be an enormous time difference between LIKE "%<text>%" versus LIKE "<text>%".

                                    1 Reply Last reply
                                    0
                                    • mbruelM Offline
                                      mbruelM Offline
                                      mbruel
                                      wrote on last edited by mbruel
                                      #18

                                      @JonB

                                      Nothing to do with your proposed timing tests

                                      maybe I wasn't clear but that's what I'm asking since the beginning. my initial goal was to use a QSortFilterProxyModel and set its regexp (cf here), so I was planing to do a LIKE "%<text>%". In fact even worst for the perf as in Qt I can do it case insensitive.

                                      My concern was to know how QSortFilterProxyModel handle a big/huge number of records. I'm testing with 40k, it is loading and filtering in few hundreds milliseconds. What about with 100k or 1M records?
                                      That is why I was considering using SQL instead. Why not FTS even, as I said since the beginning, if it would limit the search to full word or like you told me a "search for left-hand side match".

                                      So basically I was interested in any kind of benchmarks for searching either a regexp, a full word or a left-hand side match. Benchmark/Feedback on QSortFilterProxyModel and why not a comparison with SQLite or another DB.

                                      Edit: as you could imagine from the picture above, my textfield trigger a search each time the text changes (for each char :))
                                      Edit2: and yes I'm aware of the difference, I was just willing to accept limiting the search if it was lagging too much

                                      1 Reply Last reply
                                      0

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved