-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicating non-stable field expr. in query - is completely wrong and can produce wrong results #682
Comments
This is important to think about and also this is not that simple to change and fix. That's because there can be anything in expression field. It can be subquery, some fieldname, function call etc. What resulting select you would like to see instead of this ?
|
should ALWAYS be queried like
non trivial fields (or to be precise fields that are non-constant and not using constant functions) that are used multiple times must be firstly selected and then reused/conditioned using HAVING sql render using nesting is wrong, we must render to some intermediate form and then build sql once |
Nested queries should be much more faster that using But again, it will perform much slower. For example, this simple case:
This is probably faster than using Even more complexity shows up if we use both - |
@DarkSide666 this should use join if 1:1, if 1:N, your query will fail (bacause subquery will return more than 1 row) MySQL and other DBs like Oracle or MSSQL engines can probably optimize some HAVING clauses the same like subqueries nested conditions - you must query data and then you can use constant functions/junctions/operators like you want |
Yes, this example is for simple |
Can confirm that - if you have more complex hasOne/hasMany table structures, Atk4/Data gets very slow in case you add fields to child model from parent, grand-parent and grand-grand-parent tables via hasOne->addFields(...). This requires optimization, otherwise for performance reason it is much faster to load parent/grand-parent tables only where needed for single records, rather than adding those (grand-)parent fields straight into the model. If we render SQL correctly, this should not slow down SQL performance though. |
@mkrecek234 can you please post here a repro code like in #1078 (comment) for your nested usecase? |
@mvorisek Here you go - sorry not designed as a test but normal code:
|
it seems you somewhat copied the subquery like:
should be quite fast as long as the selection is done on unique index, any reasonable SQL optimizer should detect it is a 1:1 join query In chat you have written:
It would be good if you can provide the actual slow query and table metrics |
@mvorisek The example above shows a nesting, as we cascade the field down from AccountGroup via Account to Booking. If this was not what you meant, please specify what you need. On the performance I do not have performance metrics, but I can tell that complex models with down-cascaded fields slow down simple load and save model commands to a good extent. |
so no AggregateModel above is needed and |
⚠ even more conterintuitive: https://sqlite.org/forum/forumpost/8202db3916 |
Of course, I am thinking about optimal data modelling, not about implementation. Implementation is always possible.
that is the same as with Union - we need universal nesting support from Model which could result in join, union, wrap.
The current design is actually completely wrong as presented a few days ago:
Imagine field with expr
RAND() > 0
. This field is currently rendered multiple like:it is not only rand, any expression like
SELECT name FROM t LIMIT 1
is unstable as it has no explicit ORDER. Even if we (in theory, we normally do no even know them) add all table columns as a fallback order, queries likeSELECT name, COUNT(*) FROM t ORDER BY name LIMIT 1
will be still unstable because of grouping first.This is major bug which must be addressed.
Any non-trivial expression must SELECT under an alias ONCE and then this alias must be used anywhere else - https://stackoverflow.com/questions/35695171/remove-duplicate-sub-query
The text was updated successfully, but these errors were encountered: