Skip to content

Commit

Permalink
Improves pagination performance over large scale data set (#795)
Browse files Browse the repository at this point in the history
* Revert accidental change

* Do not get the total size for pagination requests
  • Loading branch information
FrankChen021 committed May 28, 2024
1 parent 3ef6fb3 commit 71f315e
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,7 @@ private String getOrderBySQL(OrderBy orderBy, String timestampColumn) {
return "";
}

if (orderBy.getName().equals(timestampColumn)) {
return StringUtils.format("ORDER BY toStartOfMinute(%s) %s, \"%s\" %s", timestampColumn, orderBy.getOrder(), orderBy.getName(), orderBy.getOrder());
} else {
return "ORDER BY \"" + orderBy.getName() + "\" " + orderBy.getOrder();
}
return "ORDER BY \"" + orderBy.getName() + "\" " + orderBy.getOrder();
}

@Override
Expand Down
19 changes: 18 additions & 1 deletion server/web-app/src/main/resources/static/js/component/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class TableComponent {
this.mColumns = option.columns;
this.mCreated = false;
this.mPopoverShown = false;
this.mTotal = 0;

this.mServerSort = option.serverSort;
this.mHasPagination = option.pagination !== undefined && option.pagination.length > 0;
Expand Down Expand Up @@ -314,7 +315,21 @@ class TableComponent {
method: 'post',
contentType: "application/json",
showRefresh: false,
responseHandler: option.responseHandler,
responseHandler: (data, jqXHR) => {
const ret = option.responseHandler(data);

if (jqXHR.status == 200 && data.limit !== undefined && data.limit !== null) {
if (data.limit.offset == 0) {
this.mTotal = ret.total;
} else {
// For pagination request, the 'total' is not returned from the server,
// But bootstrap-table requires the 'total' field tor refresh the pagination
// So we use the cached 'total'
ret.total = this.mTotal;
}
}
return ret;
},

sidePagination: this.mPaginationSide,
pagination: this.mHasPagination,
Expand All @@ -337,6 +352,8 @@ class TableComponent {
stickyHeaderOffsetRight: stickyHeaderOffsetRight,
theadClasses: 'thead-light',



onLoadError: (status, jqXHR) => {
let message = jqXHR.responseText;
if (jqXHR.responseJSON !== undefined && jqXHR.responseJSON.message !== undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class TraceListComponent {
const parent = options.parent;
this.vTable = $(parent).append('<table></table>').find('table');

this.mTotal = 0;

const excludeColumns = {};
$.each(options.excludeColumns, (index, column) => {
excludeColumns[column] = true;
Expand Down Expand Up @@ -118,6 +120,20 @@ class TraceListComponent {
return {};
},

responseHandler: (data, jqXHR) => {
if (jqXHR.status == 200) {
if (data.pageNumber == 0) {
this.mTotal = data.total;
} else {
// For pagination request, the 'total' is not returned from the server,
// But bootstrap-table requires the 'total' field tor refresh the pagination
// So we use the cached 'total'
data.total = this.mTotal;
}
}
return data;
},

onLoadError: (status, jqXHR) => {
let message;
if (jqXHR.responseJSON != null) {
Expand All @@ -136,6 +152,6 @@ class TraceListComponent {
}

refresh() {
this.vTable.bootstrapTable('refresh');
this.vTable.bootstrapTable('refresh', {pageNumber: 1});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bithon.server.storage.datasource.query.Limit;

import java.util.Collection;

Expand All @@ -34,10 +35,16 @@
public class GeneralQueryResponse {

/**
* The number of total records that satisfies the request conditions
* The number of total records that satisfies the request conditions.
* Only available when the request is performed on page 0
*/
private Integer total;

/**
* The request limit parameter
*/
private Limit limit;

private long startTimestamp;
private long endTimestamp;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,11 @@ public GeneralQueryResponse list(GeneralQueryRequest request) throws IOException

try (IDataSourceReader reader = schema.getDataStoreSpec().createReader()) {
return GeneralQueryResponse.builder()
.total(reader.listSize(query))
// Only query the total number of records for the first page
// This also has a restriction
// that the page number is not a query parameter on web page URL
.total(query.getLimit().getOffset() == 0 ? reader.listSize(query) : 0)
.limit(query.getLimit())
.data(reader.list(query))
.startTimestamp(query.getInterval().getStartTime().getMilliseconds())
.startTimestamp(query.getInterval().getEndTime().getMilliseconds())
Expand Down Expand Up @@ -285,7 +289,7 @@ private void validateQueryRequest(ISchema schema, GeneralQueryRequest request) {
.orElse(null);

Preconditions.checkIfTrue(queryField != null
&& schema.getColumnByName(queryField.getField()) != null,
&& schema.getColumnByName(queryField.getField()) != null,
"OrderBy field [%s] does not exist in the schema.",
orderBy.getName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
@AllArgsConstructor
public class GetTraceListResponse {
private int total;
private int pageNumber;
private List<TraceSpan> rows;
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ public GetTraceListResponse getTraceList(@Valid @RequestBody GetTraceListRequest
Timestamp end = TimeSpan.fromISO8601(request.getEndTimeISO8601()).toTimestamp();

return new GetTraceListResponse(
traceService.getTraceListSize(request.getFilters(), request.getExpression(), start, end),
request.getPageNumber() == 0 ? traceService.getTraceListSize(request.getFilters(), request.getExpression(), start, end) : 0,
request.getPageNumber(),
traceService.getTraceList(request.getFilters(),
request.getExpression(),
start,
Expand Down

0 comments on commit 71f315e

Please sign in to comment.