Skip to content

Commit 13f2cfd

Browse files
authored
feat(webui): Show query speed in native search status. (#1429)
1 parent 94b501b commit 13f2cfd

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {useQuery} from "@tanstack/react-query";
2+
import {Typography} from "antd";
3+
4+
import {formatSizeInBytes} from "../../../../IngestPage/Jobs/units";
5+
import useSearchStore from "../../../SearchState/index";
6+
import {SEARCH_UI_STATE} from "../../../SearchState/typings";
7+
import {fetchQuerySpeed} from "./utils";
8+
9+
10+
const {Text} = Typography;
11+
const SPEED_DEFAULT = {latency: 0, speed: 0};
12+
13+
/**
14+
* Displays the query latency and speed.
15+
*
16+
* @return
17+
*/
18+
const QuerySpeed = () => {
19+
const searchUiState = useSearchStore((state) => state.searchUiState);
20+
const searchJobId = useSearchStore((state) => state.searchJobId);
21+
const cachedDataset = useSearchStore((state) => state.cachedDataset);
22+
23+
const {data = SPEED_DEFAULT} = useQuery({
24+
queryKey: [
25+
"speed",
26+
searchJobId,
27+
cachedDataset,
28+
],
29+
queryFn: async () => {
30+
if (null === searchJobId) {
31+
return SPEED_DEFAULT;
32+
}
33+
const {bytes, duration} = await fetchQuerySpeed(cachedDataset ?? "", searchJobId);
34+
return {latency: duration, speed: bytes / duration};
35+
},
36+
enabled: SEARCH_UI_STATE.DONE === searchUiState,
37+
refetchInterval: false,
38+
});
39+
const {latency, speed} = data;
40+
return (
41+
<Text type={"secondary"}>
42+
{` in ${latency.toFixed(3)} seconds (${formatSizeInBytes(speed)}/s)`}
43+
</Text>
44+
);
45+
};
46+
47+
export default QuerySpeed;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import {querySql} from "../../../../../api/sql";
2+
import {settings} from "../../../../../settings";
3+
4+
5+
/**
6+
* Builds a SQL query string to retrieve the total uncompressed bytes and duration
7+
* for a specific query job within a given dataset.
8+
*
9+
* @param datasetName
10+
* @param jobId
11+
* @return
12+
*/
13+
const buildQuerySpeedSql = (datasetName: string, jobId: string) => {
14+
const tableName = "" === datasetName ?
15+
settings.SqlDbClpArchivesTableName :
16+
`${settings.SqlDbClpTablePrefix}${datasetName}_archives`;
17+
18+
return `WITH qt AS (
19+
SELECT job_id, archive_id
20+
FROM query_tasks
21+
WHERE
22+
archive_id IS NOT NULL
23+
AND job_id = ${jobId}
24+
),
25+
totals AS (
26+
SELECT
27+
qt.job_id,
28+
SUM(ca.uncompressed_size) AS total_uncompressed_bytes
29+
FROM qt
30+
JOIN ${tableName} ca
31+
ON qt.archive_id = ca.id
32+
)
33+
SELECT
34+
CAST(totals.total_uncompressed_bytes AS double) AS bytes,
35+
qj.duration AS duration
36+
FROM query_jobs qj
37+
JOIN totals
38+
ON totals.job_id = qj.id`;
39+
};
40+
41+
interface QuerySpeedResp {
42+
bytes: number;
43+
duration: number;
44+
}
45+
46+
/**
47+
* Fetches the query speed data (bytes and duration) for a specific job ID
48+
* within a given dataset by executing a SQL query.
49+
*
50+
* @param datasetName
51+
* @param jobId
52+
* @return
53+
*/
54+
const fetchQuerySpeed = async (datasetName: string, jobId: string): Promise<QuerySpeedResp> => {
55+
const resp = await querySql<QuerySpeedResp[]>(buildQuerySpeedSql(datasetName, jobId));
56+
const [data] = resp.data;
57+
if ("undefined" === typeof data) {
58+
throw new Error("Invalid query speed.");
59+
}
60+
61+
return data;
62+
};
63+
64+
export {fetchQuerySpeed};

components/webui/client/src/pages/SearchPage/SearchControls/QueryStatus/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {PRESTO_SQL_INTERFACE} from "../../SearchState/Presto/typings";
1010
import {SEARCH_UI_STATE} from "../../SearchState/typings";
1111
import OpenQueryDrawerButton from "./OpenQueryDrawerButton";
1212
import QueryDrawer from "./QueryDrawer";
13+
import QuerySpeed from "./QuerySpeed";
1314
import Results from "./Results";
1415

1516

@@ -90,6 +91,7 @@ const QueryStatus = () => {
9091
<Results/>
9192
{" "}
9293
<Text type={"secondary"}>results</Text>
94+
{CLP_QUERY_ENGINES.PRESTO !== SETTINGS_QUERY_ENGINE && <QuerySpeed/>}
9395
</>
9496
)}
9597
{searchUiState === SEARCH_UI_STATE.FAILED && (

0 commit comments

Comments
 (0)