-
Notifications
You must be signed in to change notification settings - Fork 13
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
Take benefit of SQLite optimization when statement is cached vs when its used once or few time and finalized quickly #791
base: main
Are you sure you want to change the base?
Conversation
…its used once or few time and finalized quickly
/azp run imodel-native |
Did you measure actual meaningful performance improvements when querying an iModel? |
IssueListener listener(*ecdb); | ||
|
||
ECSqlStatus status = m_stmt.Prepare(*ecdb, ecsql.c_str(), logErrors); | ||
ECSqlStatus status = m_stmt.Prepare(*ecdb, ecsql.c_str(), logErrors, persistent ? DbPrepareOptions::Persistent : DbPrepareOptions::None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering here, in native we have the DbPrepareOptions (Persistent is the only option), but to typescript we expose just a boolean flag.
Why not do the same thing on both sides, it seems more intuitive. Do we expect there to be more options in the future? In that case an Options object seems correct. But if persistent remains the only option, a boolean flag seems better.
Allow passing SQLITE_PREPARE_PERSISTENT to prepared statement when it is prepared with intention to be cached for multiple use.
The option avoid using lookaside memory which is use for shorter lived statement. lookaside memory allow faster prepare for single use query.
Also, note that for single-use statements, there is no guarantee of utilizing the lookaside memory pool if their state does not fit into a slot in the pool or if the pool has no empty slots. In such cases, it's allocated on the heap. By default, the lookaside memory is set to 48KB (40 slots of 1200 bytes), which is generally exhausted by cached statements. Allowing lookaside memory to be used by single-use statements can make single-use statement preparation, stepping, and finalization very fast and may not require any malloc at all.
With this change, we can prevent caching unnecessary SQLite statements and utilize single-use statements where appropriate, as they are faster to prepare and finalize compared to those allocated on the heap. The persistent flag will signal the query planner to allocate the statement on the heap when we intent to cache it.
Note: SQLite internally runs SQLite statements using either the execute or statement interface, which are also allocated on the heap. This occurs as the application has already exhausted 40 slots in the lookaside memory.
All of the following now use
SQLITE_PREPARE_PERSISTENT
option when preparing sqlite statement.itwinjs-core: iTwin/itwinjs-core#6865