Skip to content
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

Findings search / vulnerability audit performs pagination in-memory #4094

Open
2 tasks done
nscuro opened this issue Aug 23, 2024 · 0 comments
Open
2 tasks done

Findings search / vulnerability audit performs pagination in-memory #4094

nscuro opened this issue Aug 23, 2024 · 0 comments
Labels
defect Something isn't working p2 Non-critical bugs, and features that help organizations to identify and reduce risk performance size/S Small effort

Comments

@nscuro
Copy link
Member

nscuro commented Aug 23, 2024

Current Behavior

The findings search / global vulnerability audit logic performs pagination in-memory, instead of at part of the SQL query:

final Query<Object[]> query = pm.newQuery(Query.SQL, Finding.QUERY_ALL_FINDINGS + queryFilter + (this.orderBy != null ? " ORDER BY " + sortingAttributes.get(this.orderBy) + " " + (this.orderDirection == OrderDirection.DESCENDING ? " DESC" : "ASC") : ""));
PaginatedResult result = new PaginatedResult();
query.setNamedParameters(params);
final List<Object[]> totalList = query.executeList();
result.setTotal(totalList.size());
final List<Object[]> list = totalList.subList(this.pagination.getOffset(), Math.min(this.pagination.getOffset() + this.pagination.getLimit(), totalList.size()));

This means it loads everything into memory first, just to discard a big chunk of it immediately. This leads to poor performance on large portfolios and can even lead to OutOfMemoryExceptions.

Steps to Reproduce

  1. See code snippet above.

Expected Behavior

Pagination should happen in the database, using offset / limit clauses in the SQL query:

/**
* @since 4.12.0
* @return A SQL {@code OFFSET ... LIMIT ...} clause if pagination is requested, otherwise an empty string
*/
public String getOffsetLimitSqlClause() {
if (pagination == null || !pagination.isPaginated()) {
return "";
}
final String clauseTemplate;
if (DbUtil.isMssql()) {
clauseTemplate = "OFFSET %d ROWS FETCH NEXT %d ROWS ONLY";
} else if (DbUtil.isMysql()) {
// NB: Order of limit and offset is different for MySQL...
return "LIMIT %s OFFSET %s".formatted(pagination.getLimit(), pagination.getOffset());
} else {
clauseTemplate = "OFFSET %d FETCH NEXT %d ROWS ONLY";
}
return clauseTemplate.formatted(pagination.getOffset(), pagination.getLimit());
}

Dependency-Track Version

4.12.0-SNAPSHOT

Dependency-Track Distribution

Container Image, Executable WAR

Database Server

N/A

Database Server Version

No response

Browser

N/A

Checklist

@nscuro nscuro added defect Something isn't working p2 Non-critical bugs, and features that help organizations to identify and reduce risk performance size/S Small effort labels Aug 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
defect Something isn't working p2 Non-critical bugs, and features that help organizations to identify and reduce risk performance size/S Small effort
Projects
None yet
Development

No branches or pull requests

1 participant