Description
On tables with 100 million+ rows, when querying for a single row using loopback it'll insert an "order by id" forcing the entire table read.
Steps to reproduce
I am using a postgres server, but it is for pretty much all sql queries.
Example:
We have a model "foo" attached to a SQL table with the columns id
and hash
, where id
is unique, and hash
is not unique. This table has 100,000,000 Rows. and some hashes have up to 100,000 rows. (note this is simplified, in my database there are far more columns and every row is unique)
We use this curl command to query the loopback API (I know that I can use findOne instead, but it'll still go toprototype.all
so it really doesn't make a difference besides returning a single object rather than an array):
curl --location --request GET 'localhost:3000/api/foos' --header 'Content-Type: application/x-www-form-urlencoded' --form 'filter={"where": { "hash": "d41d8cd98f00b204e9800998ecf8427e" }, "limit": 1 }'
Current Behavior
Loopback generates the following SQL statement
SELECT * FROM "public"."foo" WHERE "hash"='d41d8cd98f00b204e9800998ecf8427e' ORDER BY "id" LIMIT 1
Because hash is non-unique, and can have thousands of rows, (in this case, 115,000) this takes 40.632s on my server to complete.
Expected Behavior
Loopback should instead generate the following SQL statement:
SELECT hash FROM "public"."foo" WHERE "hash"='d41d8cd98f00b204e9800998ecf8427e' LIMIT 1
resulting in a query time of on my server of 12ms.
Link to reproduction sandbox
If you really need me to setup a reproduction sandbox I can, but the problem should be pretty apparent.
Additional information
link to offending code: https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L1388
You could say that this is "working as intended" and that its the database structure is bad/wrong/whatever, but there is no reason why the connector should be dictating an order on all queries.
This functionality should be defined in the default scope of the datasource and model, not built into the base loopback connector.
Acceptance Criteria
- add a flag to disable default order by the identifier on queries. Reference: Feature: setting disable default sort loopback-connector-postgresql#417
- add test cases for main SQL connectors (MySQL for example) + mongodb
- update documentations. Might need to update several README files of connectors