Skip to content

Commit

Permalink
[fix](SqlAnalyze): Optimize sql exection plan cost chart
Browse files Browse the repository at this point in the history
  • Loading branch information
zzyangh committed Jan 23, 2025
1 parent 361b974 commit b51e3f5
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 153 deletions.
3 changes: 2 additions & 1 deletion packages/sqle/src/locale/zh-CN/sqlQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ export default {
executePlan: {
title: '执行计划{{index}}',
sql: 'SQL语句',
planCost: 'SQL执行计划 Cost趋势',
planCost: 'SQL执行计划代价趋势',
twentyFourHours: '24小时',
sevenDays: '7天',
thirtyDays: '30天',
costValue: 'Cost值',
emptyText: '暂无数据,选择其他时间段查看',
compareDifference: '对比执行计划',
historyExecPlan: '历史执行计划',
cost: '代价',
sqlExplain: '当前执行计划',
performanceStatistics: '性能统计',
affectRows: '影响行数',
Expand Down
7 changes: 5 additions & 2 deletions packages/sqle/src/page/SqlAnalyze/ManagementConf/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ const ManagementConfAnalyze = () => {
data,
getSqlExecPlanCostDataSourceLoading,
getSqlExecPlanCostDataSource,
getSqlExecPlanCostDataSourceError
getSqlExecPlanCostDataSourceError,
initTime
} = useSqlExecPlanCost(urlParams.id ?? '');

useEffect(() => {
getSqlAnalyze();
}, [getSqlAnalyze]);
getSqlExecPlanCostDataSource({ lastPointEnabled: true });
}, [getSqlAnalyze, getSqlExecPlanCostDataSource]);

return (
<SqlAnalyze
Expand All @@ -89,6 +91,7 @@ const ManagementConfAnalyze = () => {
getSqlExecPlanCostDataSourceError?.message
}
showExecPlanCostChart
initTime={initTime}
/>
);
};
Expand Down
250 changes: 140 additions & 110 deletions packages/sqle/src/page/SqlAnalyze/SqlAnalyze/ExecPlanCostChart/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Space, Button, Spin } from 'antd';
import { Space, Spin } from 'antd';
import { BasicSegmented, BasicRangePicker } from '@actiontech/shared';
import { Line, LineConfig, Tooltip } from '@ant-design/plots';
import useThemeStyleData from '../../../../hooks/useThemeStyleData';
Expand All @@ -15,6 +15,7 @@ import ChartWrapper from '../../../../components/ChartCom/ChartWrapper';
import { formatTime } from '@actiontech/shared/lib/utils/Common';
import { t } from '../../../../locale/index';
import { useChangeTheme } from '@actiontech/shared/lib/features';
import { CompareExecutionPlanButtonStyleWrapper } from './style';

const renderTooltipFormatter: Tooltip['formatter'] = (item) => {
return {
Expand All @@ -38,15 +39,17 @@ const renderTooltipCustomContent = (
}}
listData={[
{
label: t('sqlQuery.executePlan.costValue'),
label: t('sqlQuery.executePlan.cost'),
value: data.y
},
{
label: '',
value: (
<Button size="small" onClick={() => setHistoryExecPlan(data)}>
<CompareExecutionPlanButtonStyleWrapper
onClick={() => setHistoryExecPlan(data)}
>
{t('sqlQuery.executePlan.compareDifference')}
</Button>
</CompareExecutionPlanButtonStyleWrapper>
)
}
]}
Expand Down Expand Up @@ -78,6 +81,8 @@ const ExecPlanCostChart: React.FC<ExecPlanCostChartProps> = ({
DateRangeEnum['24H']
);

// const [annotations, setAnnotations] = useState<IChartPoint[]>([]);

const { data, minPoint, maxPoint, exceptUndefinedDataSource } =
useMemo(() => {
const dataSource = sqlExecPlanCostDataSource.map((i) => ({
Expand Down Expand Up @@ -110,115 +115,116 @@ const ExecPlanCostChart: React.FC<ExecPlanCostChartProps> = ({
};
}, [sqlExecPlanCostDataSource]);

const dataMarkerCommonSetting = {
type: 'dataMarker',
text: {
content: '',
style: {
textAlign: 'left'
}
},
point: {
style: {
fill: sharedTheme.basic.colorWhite,
stroke: sharedTheme.uiToken.colorPrimary
}
},
autoAdjust: false
};

const config: LineConfig = {
data,
xField: 'x',
yField: 'y',
xAxis: {
nice: true
},
point: {
style: {
fill: sharedTheme.basic.colorWhite,
stroke: sharedTheme.uiToken.colorPrimary
}
},
slider: {
start: 0,
end: 1
},
appendPadding: 20,
annotations: [
// todo 平均值和平均线 本期不需要展示 代码暂时保留
// {
// type: 'line',
// start: ['min', averageValue],
// end: ['max', averageValue],
// style: {
// stroke: sharedTheme.uiToken.colorPrimary,
// lineWidth: 2,
// lineDash: [5, 5]
// }
// },
// {
// type: 'text',
// position: ['max', averageValue],
// content: averageValue,
// offsetY: -10,
// style: {
// fill: sharedTheme.uiToken.colorPrimary,
// fontSize: 12
// }
// },
{
type: 'text',
content: renderAnnotationsContent(maxPoint?.y ?? 0),
position: renderAnnotationsPosition(maxPoint) as [string, number],
const config: LineConfig = useMemo(() => {
return {
data,
xField: 'x',
yField: 'y',
xAxis: {
nice: true
},
point: {
style: {
textAlign: 'center',
fill: sharedTheme.basic.colorWhite
fill: sharedTheme.basic.colorWhite,
stroke: sharedTheme.uiToken.colorPrimary
},
offsetY: -16,
background: {
padding: 4,
style: {
radius: 4,
fill: sharedTheme.uiToken.colorPrimary
}
}
size: 4
},
{
position: [maxPoint?.x ?? '', maxPoint?.y ?? 0],
...dataMarkerCommonSetting
slider: {
start: 0,
end: 1
},
{
type: 'text',
content: renderAnnotationsContent(minPoint?.y ?? 0),
position: renderAnnotationsPosition(minPoint) as [string, number],
style: {
textAlign: 'center',
fill: sharedTheme.basic.colorWhite
appendPadding: 20,
annotations: [
// todo 平均值和平均线 本期不需要展示 代码暂时保留
// {
// type: 'line',
// start: ['min', averageValue],
// end: ['max', averageValue],
// style: {
// stroke: sharedTheme.uiToken.colorPrimary,
// lineWidth: 2,
// lineDash: [5, 5]
// }
// },
// {
// type: 'text',
// position: ['max', averageValue],
// content: averageValue,
// offsetY: -10,
// style: {
// fill: sharedTheme.uiToken.colorPrimary,
// fontSize: 12
// }
// },
// todo 可以任意对比两个时间点的Cost 产品交互尚未完善 暂时注释相关代码
// {
// type: 'line',
// start: [annotations?.[0]?.x ?? '', 'min'],
// end: [annotations?.[0]?.x ?? '', 'max'],
// style: {
// stroke: sharedTheme.basic.colorDangerousActive,
// lineWidth: 2
// }
// },
// {
// type: 'line',
// start: [annotations?.[1]?.x ?? '', 'min'],
// end: [annotations?.[1]?.x ?? '', 'max'],
// style: {
// stroke: sharedTheme.basic.colorDangerousActive,
// lineWidth: 2
// }
// },
{
type: 'text',
content: renderAnnotationsContent(maxPoint?.y ?? 0),
position: renderAnnotationsPosition(maxPoint) as [string, number],
style: {
textAlign: 'center',
fill: sharedTheme.basic.colorWhite
},
offsetY: -16,
background: {
padding: 4,
style: {
radius: 4,
fill: sharedTheme.uiToken.colorPrimary
}
}
},
offsetY: -16,
background: {
padding: 4,
{
type: 'text',
content: renderAnnotationsContent(minPoint?.y ?? 0),
position: renderAnnotationsPosition(minPoint) as [string, number],
style: {
radius: 4,
fill: sharedTheme.uiToken.colorPrimary
textAlign: 'center',
fill: sharedTheme.basic.colorWhite
},
offsetY: -16,
background: {
padding: 4,
style: {
radius: 4,
fill: sharedTheme.uiToken.colorPrimary
}
}
}
},
{
position: [minPoint?.x ?? '', minPoint?.y ?? 0],
...dataMarkerCommonSetting
],
tooltip: {
fields: ['created_time', 'cost', 'id'],
enterable: true,
follow: true,
formatter: renderTooltipFormatter,
customContent: (title: string, dataSource: any[]) =>
renderTooltipCustomContent(
dataSource,
sharedTheme,
setHistoryExecPlan
)
}
],
tooltip: {
fields: ['created_time', 'cost', 'id'],
enterable: true,
follow: true,
formatter: renderTooltipFormatter,
customContent: (title: string, dataSource: any[]) =>
renderTooltipCustomContent(dataSource, sharedTheme, setHistoryExecPlan)
}
};
};
}, [data, maxPoint, minPoint, sharedTheme, setHistoryExecPlan]);

const onSegmentedChange = (value: SegmentedValue) => {
setTimePeriod(value as DateRangeEnum);
Expand All @@ -229,7 +235,11 @@ const ExecPlanCostChart: React.FC<ExecPlanCostChartProps> = ({
} else if (value === DateRangeEnum['30D']) {
startTime = dayjs().subtract(30, 'day');
}
getSqlExecPlanCostDataSource?.(startTime, endTime);
getSqlExecPlanCostDataSource?.({
startTime,
endTime,
lastPointEnabled: value === DateRangeEnum['24H']
});
};

const onRefresh = () => {
Expand All @@ -254,10 +264,10 @@ const ExecPlanCostChart: React.FC<ExecPlanCostChartProps> = ({
}}
onChange={(value) => {
if (value) {
getSqlExecPlanCostDataSource?.(
value?.[0] ?? undefined,
value?.[1] ?? undefined
);
getSqlExecPlanCostDataSource?.({
startTime: value?.[0] ?? undefined,
endTime: value?.[1] ?? undefined
});
} else {
onSegmentedChange(timePeriod);
}
Expand All @@ -274,7 +284,27 @@ const ExecPlanCostChart: React.FC<ExecPlanCostChartProps> = ({
emptyCont={t('sqlQuery.executePlan.emptyText')}
onRefresh={onRefresh}
>
<Line {...config} theme={currentTheme} />
<Line
{...config}
theme={currentTheme}
// todo 可以任意对比两个时间点的Cost 产品交互尚未完善 暂时注释相关代码
// onEvent={(chart, event) => {
// const { type } = event;
// if (type === 'point:click') {
// // updateChart(event);
// setAnnotations((state) => {
// const { x } = event.data?.data ?? {};
// if (state.some((i) => i.x === x)) {
// return state.filter((i) => i.x !== x);
// }
// if (state.length < 2) {
// return [...state, event.data?.data];
// }
// return state;
// });
// }
// }}
/>
</ChartWrapper>
</Spin>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { styled } from '@mui/material/styles';

export const CompareExecutionPlanButtonStyleWrapper = styled('span')`
cursor: pointer;
`;
6 changes: 4 additions & 2 deletions packages/sqle/src/page/SqlAnalyze/SqlAnalyze/SqlAnalyze.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const SqlAnalyze: React.FC<SqlAnalyzeProps> = (props) => {
getSqlExecPlanCostDataSource,
getSqlExecPlanCostDataSourceLoading,
getSqlExecPlanCostDataSourceError,
showExecPlanCostChart
showExecPlanCostChart,
initTime
} = props;

const { generateTableSchemaContent } = useTableSchema();
Expand All @@ -36,7 +37,8 @@ const SqlAnalyze: React.FC<SqlAnalyzeProps> = (props) => {
getSqlExecPlanCostDataSource,
getSqlExecPlanCostDataSourceLoading,
getSqlExecPlanCostDataSourceError,
showExecPlanCostChart
showExecPlanCostChart,
initTime
});

const [tabStatus, setTabStatus] = useState<string>('sql');
Expand Down
Loading

0 comments on commit b51e3f5

Please sign in to comment.