console: optimise count fetch in data browser (#4692)

* in table-browse-rows, make intelligent count

* update changelog

* simplify getting estimatedCount

* prevent doubled requests

* hide estimated count

* update changelog

* Update CHANGELOG.md

Co-authored-by: Rishichandra Wawhal <rishi@hasura.io>
Co-authored-by: Aleksandra Sikora <ola.zxcvbnm@gmail.com>
This commit is contained in:
Rikin Kachhia 2020-05-06 23:37:56 +05:30 committed by GitHub
parent e14352eb72
commit c2fdcd0471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 10 deletions

View File

@ -36,6 +36,7 @@ Read more about the session argument for computed fields in the [docs](https://h
(Add entries here in the order of: server, console, cli, docs, others) (Add entries here in the order of: server, console, cli, docs, others)
- console: avoid count queries for large tables (#4692)
- console: add read replica support section to pro popup (#4118) - console: add read replica support section to pro popup (#4118)
- cli: list all avialable commands in root command help (fix #4623) - cli: list all avialable commands in root command help (fix #4623)

View File

@ -22,6 +22,8 @@ const defaultViewState = {
manualTriggers: [], manualTriggers: [],
triggeredRow: -1, triggeredRow: -1,
triggeredFunction: null, triggeredFunction: null,
estimatedCount: 0,
isCountEstimated: 0,
}; };
const defaultPermissionsState = { const defaultPermissionsState = {

View File

@ -27,6 +27,7 @@ import Button from '../../../Common/Button/Button';
import ReloadEnumValuesButton from '../Common/Components/ReloadEnumValuesButton'; import ReloadEnumValuesButton from '../Common/Components/ReloadEnumValuesButton';
import styles from '../../../Common/FilterQuery/FilterQuery.scss'; import styles from '../../../Common/FilterQuery/FilterQuery.scss';
import { getPersistedPageSize } from './localStorageUtils'; import { getPersistedPageSize } from './localStorageUtils';
import { isEmpty } from '../../../Common/utils/jsUtils';
const history = createHistory(); const history = createHistory();
@ -205,7 +206,7 @@ class FilterQuery extends Component {
componentDidMount() { componentDidMount() {
const { dispatch, tableSchema, curQuery } = this.props; const { dispatch, tableSchema, curQuery } = this.props;
const limit = getPersistedPageSize(); const limit = getPersistedPageSize();
if (!this.props.urlQuery) { if (isEmpty(this.props.urlQuery)) {
dispatch(setDefaultQuery({ ...curQuery, limit })); dispatch(setDefaultQuery({ ...curQuery, limit }));
return; return;
} }

View File

@ -17,6 +17,7 @@ import {
getRunSqlQuery, getRunSqlQuery,
} from '../../../Common/utils/v1QueryUtils'; } from '../../../Common/utils/v1QueryUtils';
import { generateTableDef } from '../../../Common/utils/pgUtils'; import { generateTableDef } from '../../../Common/utils/pgUtils';
import { COUNT_LIMIT } from '../constants';
/* ****************** View actions *************/ /* ****************** View actions *************/
const V_SET_DEFAULTS = 'ViewTable/V_SET_DEFAULTS'; const V_SET_DEFAULTS = 'ViewTable/V_SET_DEFAULTS';
@ -96,7 +97,7 @@ const vMakeRowsRequest = () => {
dispatch({ dispatch({
type: V_REQUEST_SUCCESS, type: V_REQUEST_SUCCESS,
data: data[0], data: data[0],
estimatedCount: data[1].result[1], estimatedCount: parseInt(data[1].result[1][0], 10),
}), }),
dispatch({ type: V_REQUEST_PROGRESS, data: false }), dispatch({ type: V_REQUEST_PROGRESS, data: false }),
]); ]);
@ -157,9 +158,19 @@ const vMakeCountRequest = () => {
}; };
}; };
const vMakeTableRequests = () => dispatch => { const vMakeTableRequests = () => (dispatch, getState) => {
dispatch(vMakeRowsRequest()); dispatch(vMakeRowsRequest()).then(() => {
dispatch(vMakeCountRequest()); const { estimatedCount } = getState().tables.view;
if (estimatedCount > COUNT_LIMIT) {
dispatch({
type: V_COUNT_REQUEST_SUCCESS,
count: estimatedCount,
isEstimated: true,
});
} else {
dispatch(vMakeCountRequest());
}
});
}; };
const fetchManualTriggers = tableName => { const fetchManualTriggers = tableName => {
@ -572,7 +583,11 @@ const viewReducer = (tableName, currentSchema, schemas, viewState, action) => {
case V_REQUEST_PROGRESS: case V_REQUEST_PROGRESS:
return { ...viewState, isProgressing: action.data }; return { ...viewState, isProgressing: action.data };
case V_COUNT_REQUEST_SUCCESS: case V_COUNT_REQUEST_SUCCESS:
return { ...viewState, count: action.count }; return {
...viewState,
count: action.count,
isCountEstimated: action.isEstimated === true,
};
case V_EXPAND_ROW: case V_EXPAND_ROW:
return { return {
...viewState, ...viewState,

View File

@ -110,6 +110,7 @@ class ViewTable extends Component {
triggeredFunction, triggeredFunction,
location, location,
estimatedCount, estimatedCount,
isCountEstimated,
} = this.props; } = this.props;
// check if table exists // check if table exists
@ -161,7 +162,8 @@ class ViewTable extends Component {
// Choose the right nav bar header thing // Choose the right nav bar header thing
const header = ( const header = (
<TableHeader <TableHeader
count={count} count={isCountEstimated ? estimatedCount : count}
isCountEstimated={isCountEstimated}
dispatch={dispatch} dispatch={dispatch}
table={tableSchema} table={tableSchema}
tabName="browse" tabName="browse"

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Link } from 'react-router'; import { Link } from 'react-router';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { changeTableName } from '../TableModify/ModifyActions'; import { changeTableName } from '../TableModify/ModifyActions';
import { capitalize } from '../../../Common/utils/jsUtils'; import { capitalize, exists } from '../../../Common/utils/jsUtils';
import EditableHeading from '../../../Common/EditableHeading/EditableHeading'; import EditableHeading from '../../../Common/EditableHeading/EditableHeading';
import BreadCrumb from '../../../Common/Layout/BreadCrumb/BreadCrumb'; import BreadCrumb from '../../../Common/Layout/BreadCrumb/BreadCrumb';
import { tabNameMap } from '../utils'; import { tabNameMap } from '../utils';
@ -26,6 +26,7 @@ import { getReadableNumber } from '../../../Common/utils/jsUtils';
const TableHeader = ({ const TableHeader = ({
tabName, tabName,
count, count,
isCountEstimated,
table, table,
migrationMode, migrationMode,
readOnlyMode, readOnlyMode,
@ -38,8 +39,11 @@ const TableHeader = ({
const isTable = checkIfTable(table); const isTable = checkIfTable(table);
let countDisplay = ''; let countDisplay = '';
if (!(count === null || count === undefined)) { // if (exists(count)) {
countDisplay = '(' + getReadableNumber(count) + ')'; // countDisplay = `(${isCountEstimated ? '~' : '' }${getReadableNumber(count)})`;
// }
if (exists(count) && !isCountEstimated) {
countDisplay = `(${getReadableNumber(count)})`;
} }
const activeTab = tabNameMap[tabName]; const activeTab = tabNameMap[tabName];

View File

@ -38,6 +38,8 @@ export const Integers = [
'bigint', 'bigint',
]; ];
export const COUNT_LIMIT = 100000;
export const Reals = ['float4', 'float8', 'numeric']; export const Reals = ['float4', 'float8', 'numeric'];
export const Numerics = [...Integers, ...Reals]; export const Numerics = [...Integers, ...Reals];