Browse Source

fix: Postgres rows count of large tables

query optimized to handle large tables row count

re #283

Signed-off-by: Pranav C Balan <pranavxc@gmail.com>
pull/293/head
Pranav C Balan 3 years ago
parent
commit
5c06d35ad2
  1. 53
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  2. 22
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts

53
packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue

@ -214,32 +214,35 @@
</template> </template>
</div> </div>
<v-pagination <template v-if="data">
v-if="data && count !== Infinity" <v-pagination
style="max-width: 100%" v-if="count !== Infinity"
v-model="page" style="max-width: 100%"
:length="Math.ceil(count / size)"
:total-visible="8"
@input="loadTableData"
color="primary lighten-2"
></v-pagination>
<div class="mx-auto d-flex align-center mt-n1 " style="max-width:250px">
<span class="caption" style="white-space: nowrap"> Change page:</span>
<v-text-field
class="ml-1 caption"
:full-width="false"
outlined
dense
hide-details
v-model="page" v-model="page"
@keydown.enter="loadTableData" :length="Math.ceil(count / size)"
type="number" :total-visible="8"
> @input="loadTableData"
<template #append> color="primary lighten-2"
<x-icon tooltip="Change page" small icon.class="mt-1" @click="loadTableData">mdi-keyboard-return</x-icon> ></v-pagination>
</template> <div v-else class="mx-auto d-flex align-center mt-n1 " style="max-width:250px">
</v-text-field> <span class="caption" style="white-space: nowrap"> Change page:</span>
</div> <v-text-field
class="ml-1 caption"
:full-width="false"
outlined
dense
hide-details
v-model="page"
@keydown.enter="loadTableData"
type="number"
>
<template #append>
<x-icon tooltip="Change page" small icon.class="mt-1" @click="loadTableData">mdi-keyboard-return
</x-icon>
</template>
</v-text-field>
</div>
</template>
<!-- <div v-else class="d-flex justify-center py-4">--> <!-- <div v-else class="d-flex justify-center py-4">-->
<!-- <v-alert type="info" dense class="ma-1 flex-shrink-1">Table is empty</v-alert>--> <!-- <v-alert type="info" dense class="ma-1 flex-shrink-1">Table is empty</v-alert>-->
<!-- </div>--> <!-- </div>-->

22
packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts

@ -252,8 +252,8 @@ class BaseModelSql extends BaseModel {
const query = driver(this.tn).insert(insertObj); const query = driver(this.tn).insert(insertObj);
if (this.dbDriver.clientType() === 'pg' || this.dbDriver.clientType() === 'mssql') { if (this.isPg() || this.dbDriver.clientType() === 'mssql') {
query.returning(Object.entries(this.aliasToColumn).map(([val,key]) => `${key} as ${val}`)); query.returning(Object.entries(this.aliasToColumn).map(([val, key]) => `${key} as ${val}`));
response = await this._run(query); response = await this._run(query);
} }
@ -282,6 +282,10 @@ class BaseModelSql extends BaseModel {
} }
private isPg() {
return this.dbDriver.clientType() === 'pg';
}
/** /**
* Update table row data by primary key * Update table row data by primary key
* *
@ -800,6 +804,16 @@ class BaseModelSql extends BaseModel {
*/ */
async countByPk({where = '', conditionGraph = null}) { async countByPk({where = '', conditionGraph = null}) {
try { try {
if (this.isPg() && !conditionGraph && !where) {
return (await this._run(
this.dbDriver.raw(`SELECT c.reltuples::bigint AS count
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = ?
AND n.nspname = ?`, [this.tn,this.config?.searchPath?.[0] || 'public'])
))?.rows?.[0];
}
return await this._run(this.$db return await this._run(this.$db
.conditionGraph(conditionGraph) .conditionGraph(conditionGraph)
.count(`${this.tn}.${(this.pks[0] || this.columns[0]).cn} as count`) .count(`${this.tn}.${(this.pks[0] || this.columns[0]).cn} as count`)
@ -1103,7 +1117,7 @@ class BaseModelSql extends BaseModel {
.select(this.dbModels[child].selectQuery(fields)) // ...fields.split(',')); .select(this.dbModels[child].selectQuery(fields)) // ...fields.split(','));
this._paginateAndSort(query, {sort, limit, offset}, null,true); this._paginateAndSort(query, {sort, limit, offset}, null, true);
return this.isSqlite() ? this.dbDriver.select().from(query) : query; return this.isSqlite() ? this.dbDriver.select().from(query) : query;
}), !this.isSqlite() }), !this.isSqlite()
)); ));
@ -1370,7 +1384,7 @@ class BaseModelSql extends BaseModel {
* @returns {Object} query appended with paginate and sort params * @returns {Object} query appended with paginate and sort params
* @private * @private
*/ */
_paginateAndSort(query, {limit = 20, offset = 0, sort = ''}: XcFilter, table?: string, isUnion?:boolean) { _paginateAndSort(query, {limit = 20, offset = 0, sort = ''}: XcFilter, table?: string, isUnion?: boolean) {
query.offset(offset) query.offset(offset)
.limit(limit); .limit(limit);

Loading…
Cancel
Save