Tentative fix for bad query perf with recent sqlite versions: limit 1 seems to be culprit
This commit is contained in:
@@ -114,7 +114,7 @@ namespace lms::db
|
|||||||
|
|
||||||
std::string table;
|
std::string table;
|
||||||
std::string foreignTable;
|
std::string foreignTable;
|
||||||
// see https://www.sqlite.org/pragma.html#pragma_foreign_key_check for exepcted result
|
// see https://www.sqlite.org/pragma.html#pragma_foreign_key_check for expected result
|
||||||
while (statement->nextRow())
|
while (statement->nextRow())
|
||||||
{
|
{
|
||||||
foreignKeyConstraintsPassed = false;
|
foreignKeyConstraintsPassed = false;
|
||||||
@@ -132,6 +132,57 @@ namespace lms::db
|
|||||||
|
|
||||||
return foreignKeyConstraintsPassed;
|
return foreignKeyConstraintsPassed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<int> getPageSize(Wt::Dbo::SqlConnection& connection)
|
||||||
|
{
|
||||||
|
auto statement = connection.prepareStatement("PRAGMA page_size");
|
||||||
|
statement->execute();
|
||||||
|
|
||||||
|
std::optional<int> res;
|
||||||
|
while (statement->nextRow())
|
||||||
|
{
|
||||||
|
assert(!res);
|
||||||
|
int value{};
|
||||||
|
if (statement->getResult(0, &value))
|
||||||
|
res = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<int> getCacheSize(Wt::Dbo::SqlConnection& connection)
|
||||||
|
{
|
||||||
|
auto statement = connection.prepareStatement("PRAGMA cache_size");
|
||||||
|
statement->execute();
|
||||||
|
|
||||||
|
std::optional<int> res;
|
||||||
|
while (statement->nextRow())
|
||||||
|
{
|
||||||
|
assert(!res);
|
||||||
|
int value{};
|
||||||
|
if (statement->getResult(0, &value))
|
||||||
|
res = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getCompileOptions(Wt::Dbo::SqlConnection& connection, std::function<void(std::string_view compileOption)> callback)
|
||||||
|
{
|
||||||
|
auto statement = connection.prepareStatement("PRAGMA compile_options");
|
||||||
|
statement->execute();
|
||||||
|
|
||||||
|
std::string res;
|
||||||
|
while (statement->nextRow())
|
||||||
|
{
|
||||||
|
res.clear();
|
||||||
|
|
||||||
|
if (statement->getResult(0, &res, static_cast<int>(res.capacity())))
|
||||||
|
callback(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<IDb> createDb(const std::filesystem::path& dbPath, std::size_t connectionCount)
|
std::unique_ptr<IDb> createDb(const std::filesystem::path& dbPath, std::size_t connectionCount)
|
||||||
@@ -157,6 +208,13 @@ namespace lms::db
|
|||||||
|
|
||||||
_connectionPool = std::move(connectionPool);
|
_connectionPool = std::move(connectionPool);
|
||||||
|
|
||||||
|
executeSql("PRAGMA temp_store=MEMORY");
|
||||||
|
executeSql("PRAGMA cache_size=-8000");
|
||||||
|
executeSql("PRAGMA automatic_index=0");
|
||||||
|
|
||||||
|
logPageSize();
|
||||||
|
logCacheSize();
|
||||||
|
logCompileOptions();
|
||||||
if (checkType == "quick")
|
if (checkType == "quick")
|
||||||
{
|
{
|
||||||
performQuickCheck();
|
performQuickCheck();
|
||||||
@@ -199,6 +257,34 @@ namespace lms::db
|
|||||||
return *tlsSession;
|
return *tlsSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Db::logPageSize()
|
||||||
|
{
|
||||||
|
ScopedConnection connection{ *_connectionPool };
|
||||||
|
const std::optional<int> pageSize{ getPageSize(*connection) };
|
||||||
|
|
||||||
|
if (pageSize)
|
||||||
|
LMS_LOG(DB, INFO, "Page size set to " << *pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Db::logCacheSize()
|
||||||
|
{
|
||||||
|
ScopedConnection connection{ *_connectionPool };
|
||||||
|
const std::optional<int> cacheSize{ getCacheSize(*connection) };
|
||||||
|
|
||||||
|
if (cacheSize)
|
||||||
|
LMS_LOG(DB, INFO, "Cache size set to " << *cacheSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Db::logCompileOptions()
|
||||||
|
{
|
||||||
|
ScopedConnection connection{ *_connectionPool };
|
||||||
|
|
||||||
|
LMS_LOG(DB, INFO, "Sqlite3 compile options:");
|
||||||
|
getCompileOptions(*connection, [](std::string_view compileOption) {
|
||||||
|
LMS_LOG(DB, INFO, compileOption);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Db::performQuickCheck()
|
void Db::performQuickCheck()
|
||||||
{
|
{
|
||||||
ScopedConnection connection{ *_connectionPool };
|
ScopedConnection connection{ *_connectionPool };
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ namespace lms::db
|
|||||||
core::RecursiveSharedMutex& getMutex() { return _sharedMutex; }
|
core::RecursiveSharedMutex& getMutex() { return _sharedMutex; }
|
||||||
Wt::Dbo::SqlConnectionPool& getConnectionPool() { return *_connectionPool; }
|
Wt::Dbo::SqlConnectionPool& getConnectionPool() { return *_connectionPool; }
|
||||||
|
|
||||||
|
void logPageSize();
|
||||||
|
void logCacheSize();
|
||||||
|
void logCompileOptions();
|
||||||
void performQuickCheck();
|
void performQuickCheck();
|
||||||
void performIntegrityCheck();
|
void performIntegrityCheck();
|
||||||
void performForeignKeyConstraintsCheck();
|
void performForeignKeyConstraintsCheck();
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ namespace lms::db::utils
|
|||||||
if (range)
|
if (range)
|
||||||
{
|
{
|
||||||
query.limit(static_cast<int>(range->size));
|
query.limit(static_cast<int>(range->size));
|
||||||
query.offset(static_cast<int>(range->offset));
|
if (range->offset != 0)
|
||||||
|
query.offset(static_cast<int>(range->offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace lms::db
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.imageType.has_value())
|
if (params.imageType.has_value())
|
||||||
query.where("+t_e_i_l.type = ?").bind(params.imageType.value()); // hack: type is a bad way to reduce the result space
|
query.where("t_e_i_l.type = ?").bind(params.imageType.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (params.sortMethod)
|
switch (params.sortMethod)
|
||||||
|
|||||||
@@ -142,9 +142,10 @@ namespace lms::scanner
|
|||||||
params.setRelease(release->getId());
|
params.setRelease(release->getId());
|
||||||
params.setImageType(db::ImageType::FrontCover);
|
params.setImageType(db::ImageType::FrontCover);
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::DiscNumberThenTrackNumberThenSizeDesc);
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::DiscNumberThenTrackNumberThenSizeDesc);
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
||||||
|
if (!artwork)
|
||||||
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) { artwork = db::Artwork::find(session, image->getId()); });
|
artwork = db::Artwork::find(session, image->getId());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (artwork)
|
if (artwork)
|
||||||
@@ -156,9 +157,10 @@ namespace lms::scanner
|
|||||||
params.setRelease(release->getId());
|
params.setRelease(release->getId());
|
||||||
params.setImageType(db::ImageType::Media);
|
params.setImageType(db::ImageType::Media);
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::DiscNumberThenTrackNumberThenSizeDesc);
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::DiscNumberThenTrackNumberThenSizeDesc);
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
||||||
|
if (!artwork)
|
||||||
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) { artwork = db::Artwork::find(session, image->getId()); });
|
artwork = db::Artwork::find(session, image->getId());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return artwork;
|
return artwork;
|
||||||
|
|||||||
@@ -65,8 +65,11 @@ namespace lms::scanner
|
|||||||
params.setTrack(track->getId());
|
params.setTrack(track->getId());
|
||||||
params.setImageType(db::ImageType::FrontCover);
|
params.setImageType(db::ImageType::FrontCover);
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::SizeDesc);
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::SizeDesc);
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
|
||||||
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) { res = db::Artwork::find(session, image->getId()); });
|
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
||||||
|
if (!res)
|
||||||
|
res = db::Artwork::find(session, image->getId());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
@@ -92,8 +95,11 @@ namespace lms::scanner
|
|||||||
params.setTrack(track->getId());
|
params.setTrack(track->getId());
|
||||||
params.setImageType(db::ImageType::Media);
|
params.setImageType(db::ImageType::Media);
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::SizeDesc);
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::SizeDesc);
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
|
||||||
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) { res = db::Artwork::find(session, image->getId()); });
|
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
||||||
|
if (!res)
|
||||||
|
res = db::Artwork::find(session, image->getId());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
@@ -111,8 +117,11 @@ namespace lms::scanner
|
|||||||
params.setDiscNumber(discNumber);
|
params.setDiscNumber(discNumber);
|
||||||
params.setImageType(db::ImageType::Media);
|
params.setImageType(db::ImageType::Media);
|
||||||
params.setSortMethod(db::TrackEmbeddedImageSortMethod::TrackNumberThenSizeDesc);
|
params.setSortMethod(db::TrackEmbeddedImageSortMethod::TrackNumberThenSizeDesc);
|
||||||
params.setRange(db::Range{ .offset = 0, .size = 1 });
|
|
||||||
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) { res = db::Artwork::find(session, image->getId()); });
|
db::TrackEmbeddedImage::find(session, params, [&](const db::TrackEmbeddedImage::pointer& image) {
|
||||||
|
if (!res)
|
||||||
|
res = db::Artwork::find(session, image->getId());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
Reference in New Issue
Block a user