# HG changeset patch # User Alain Mazy # Date 1790773085 -7200 # Node ID 6d0f6a686b71f42e9cdd06bb65a857dc5367abd0 # Parent 22083f3fe932f141e72ee361cfacdb3131b94f2f moved the DB specific criteria to run ANALYZE out of the OrthancFramework diff -r 22083f3fe932 -r 6d0f6a686b71 OrthancFramework/Sources/SQLite/Connection.cpp --- a/OrthancFramework/Sources/SQLite/Connection.cpp Wed Sep 30 14:17:23 2026 +0200 +++ b/OrthancFramework/Sources/SQLite/Connection.cpp Wed Sep 30 14:58:05 2026 +0200 @@ -232,20 +232,15 @@ return false; } - void Connection::Optimize(bool onlyIfStatsDontExists) + void Connection::Optimize(bool onlyIfStatsDontExistsYet) { - if (onlyIfStatsDontExists) + if (onlyIfStatsDontExistsYet) { if (!DoesTableExist("sqlite_stat1")) // create the table if it does not exist yet and if there are enough data in the Resources table { - Statement countResources(*this, std::string("SELECT COUNT(*) FROM Resources WHERE resourceType=") + boost::lexical_cast(ResourceType_Study)); - countResources.Step(); - if (countResources.ColumnInt64(0) > 50) // no need to ANALYZE if there are not enough data in the table (wait for 50 studies) - { - CLOG(WARNING, SQLITE) << "SQLite: Performing first ANALYZE to improve the query planner"; - Statement analyze(*this, "ANALYZE"); - analyze.Run(); - } + CLOG(WARNING, SQLITE) << "SQLite: Performing first ANALYZE to improve the query planner"; + Statement analyze(*this, "ANALYZE"); + analyze.Run(); } } else diff -r 22083f3fe932 -r 6d0f6a686b71 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Wed Sep 30 14:17:23 2026 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Wed Sep 30 14:58:05 2026 +0200 @@ -2884,8 +2884,8 @@ ExecuteEmbeddedScript(db_, ServerResources::ADD_TIMEOUT_TO_QUEUES); } - // New in Orthanc 1.13.1 run optimize at each startup - db_.Optimize(false); + // New in Orthanc 1.13.1 run optimize at each startup, provided there are enough data to perform a relevant analysis + Optimize(false); } transaction->Commit(0); @@ -3020,12 +3020,32 @@ } + bool SQLiteDatabaseWrapper::Optimize(bool onlyIfStatsDontExistsYet) + { + SQLite::Statement countResources(db_, std::string("SELECT COUNT(*) FROM Resources WHERE resourceType=") + boost::lexical_cast(ResourceType_Study)); + countResources.Step(); + + if (countResources.ColumnInt64(0) > 50) // no need to ANALYZE if there are not enough data in the table (wait for 50 studies) + { + db_.Optimize(onlyIfStatsDontExistsYet); + return true; + } + + return false; + } + + void SQLiteDatabaseWrapper::FlushToDisk() { boost::recursive_mutex::scoped_lock lock(mutex_); - - // this will run ANALYZE only once whe the Resources table contains enough rows - db_.Optimize(true); + static bool hasRunOptimizeOnce = false; + + if (!hasRunOptimizeOnce) + { + // This will run ANALYZE only once whe the Resources table contains reaches a predefined size and if there are no index statistics yet. + // Then, an OPTIMIZE step will run at each startup (and will execute ANALYZE if it makes sense) + hasRunOptimizeOnce = Optimize(true /* onlyIfStatsDontExistsYet */); + } db_.FlushToDisk(); } diff -r 22083f3fe932 -r 6d0f6a686b71 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h Wed Sep 30 14:17:23 2026 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h Wed Sep 30 14:58:05 2026 +0200 @@ -65,6 +65,8 @@ SQLite::Statement& s, uint32_t maxResults); + bool Optimize(bool onlyIfStatsDontExistsYet); + public: SQLiteDatabaseWrapper(const std::string& path);