You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-26 22:41:17 +02:00
Server: Fix severe performance issue for certain delta calls
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import Logger from '@joplin/utils/Logger';
|
import Logger from '@joplin/utils/Logger';
|
||||||
import { SqliteMaxVariableNum } from '../db';
|
import { SqliteMaxVariableNum, isPostgres } from '../db';
|
||||||
import { Change, ChangeType, Item, Uuid } from '../services/database/types';
|
import { Change, ChangeType, Item, Uuid } from '../services/database/types';
|
||||||
import { md5 } from '../utils/crypto';
|
import { md5 } from '../utils/crypto';
|
||||||
import { ErrorResyncRequired } from '../utils/errors';
|
import { ErrorResyncRequired } from '../utils/errors';
|
||||||
@@ -191,16 +191,41 @@ export default class ChangeModel extends BaseModel<Change> {
|
|||||||
|
|
||||||
const finalParams = subParams1.concat(subParams2);
|
const finalParams = subParams1.concat(subParams2);
|
||||||
|
|
||||||
|
// For Postgres, we need to use materialized tables because, even
|
||||||
|
// though each independant query is fast, the query planner end up going
|
||||||
|
// for a very slow plan when they are combined with UNION ALL.
|
||||||
|
// https://dba.stackexchange.com/a/333147/37012
|
||||||
|
//
|
||||||
|
// Normally we could use the same query for SQLite since it supports
|
||||||
|
// materialized views too, but it doesn't work for some reason so we
|
||||||
|
// keep the non-optimised query.
|
||||||
|
|
||||||
if (!doCountQuery) {
|
if (!doCountQuery) {
|
||||||
finalParams.push(limit);
|
finalParams.push(limit);
|
||||||
|
|
||||||
query = this.db.raw(`
|
if (isPostgres(this.db)) {
|
||||||
SELECT ${fieldsSql} FROM (${subQuery1}) as sub1
|
query = this.db.raw(`
|
||||||
UNION ALL
|
WITH cte1 AS MATERIALIZED (
|
||||||
SELECT ${fieldsSql} FROM (${subQuery2}) as sub2
|
${subQuery1}
|
||||||
ORDER BY counter ASC
|
)
|
||||||
LIMIT ?
|
, cte2 AS MATERIALIZED (
|
||||||
`, finalParams);
|
${subQuery2}
|
||||||
|
)
|
||||||
|
TABLE cte1
|
||||||
|
UNION ALL
|
||||||
|
TABLE cte2
|
||||||
|
ORDER BY counter ASC
|
||||||
|
LIMIT ?
|
||||||
|
`, finalParams);
|
||||||
|
} else {
|
||||||
|
query = this.db.raw(`
|
||||||
|
SELECT ${fieldsSql} FROM (${subQuery1}) as sub1
|
||||||
|
UNION ALL
|
||||||
|
SELECT ${fieldsSql} FROM (${subQuery2}) as sub2
|
||||||
|
ORDER BY counter ASC
|
||||||
|
LIMIT ?
|
||||||
|
`, finalParams);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
query = this.db.raw(`
|
query = this.db.raw(`
|
||||||
SELECT count(*) as total
|
SELECT count(*) as total
|
||||||
|
|||||||
Reference in New Issue
Block a user