优化了in/not in的SQL语句
This commit is contained in:
parent
c789457f96
commit
09715010e4
|
|
@ -617,43 +617,58 @@ class SqlTranslator {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const fk = foreignKey || 'entityId';
|
const fk = foreignKey || 'entityId';
|
||||||
const joinFilter = {
|
// 对in和not in优化,不要用exists查询
|
||||||
$expr12: {
|
if (['in', 'not in'].includes(predicate)) {
|
||||||
$eq: [
|
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
||||||
{
|
data: {
|
||||||
'#attr': fk,
|
[fk]: 1,
|
||||||
},
|
},
|
||||||
{
|
filter: filter2[attr]
|
||||||
'#refId': refAlia2,
|
}, currentNumber, filterRefAlias, option);
|
||||||
'#refAttr': 'id',
|
currentNumber = ct2;
|
||||||
}
|
whereText += `(${refAlia2}.id ${predicate} (${stmt}))`;
|
||||||
],
|
}
|
||||||
}
|
else {
|
||||||
};
|
/**
|
||||||
if (!foreignKey) {
|
* 只剩下all/not all
|
||||||
Object.assign(joinFilter, {
|
* 翻译成键值不等条件下的not exist/exist
|
||||||
entity: entity2,
|
*/
|
||||||
});
|
const joinFilter = {
|
||||||
|
$expr83: {
|
||||||
|
[['all', 'not all'].includes(predicate) ? '$ne' : '$eq']: [
|
||||||
|
{
|
||||||
|
'#attr': fk,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'#refId': refAlia2,
|
||||||
|
'#refAttr': 'id',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!foreignKey) {
|
||||||
|
Object.assign(joinFilter, {
|
||||||
|
entity: entity2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
filter: (0, filter_1.combineFilters)(subEntity, this.schema, [joinFilter, filter2[attr]]),
|
||||||
|
indexFrom: 0,
|
||||||
|
count: 1,
|
||||||
|
}, currentNumber, filterRefAlias, option);
|
||||||
|
currentNumber = ct2;
|
||||||
|
const PREDICATE_DICT = {
|
||||||
|
// in 和 not in已经不会命中了(优化到上面的路径中)
|
||||||
|
'in': 'exists',
|
||||||
|
'not in': 'not exists',
|
||||||
|
'all': 'not exists',
|
||||||
|
'not all': 'exists',
|
||||||
|
};
|
||||||
|
whereText += ` ${PREDICATE_DICT[predicate]} (${stmt})`;
|
||||||
}
|
}
|
||||||
const conditionalPredicate = ['all', 'not all'].includes(predicate) ? {
|
|
||||||
$not: filter2[attr],
|
|
||||||
} : filter2[attr];
|
|
||||||
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
},
|
|
||||||
filter: (0, filter_1.combineFilters)(subEntity, this.schema, [joinFilter, conditionalPredicate]),
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
}, currentNumber, filterRefAlias, option);
|
|
||||||
currentNumber = ct2;
|
|
||||||
const PREDICATE_DICT = {
|
|
||||||
'in': 'exists',
|
|
||||||
'not in': 'not exists',
|
|
||||||
'all': 'not exists',
|
|
||||||
'not all': 'exists',
|
|
||||||
};
|
|
||||||
whereText += ` ${PREDICATE_DICT[predicate]} (${stmt})`;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(0, assert_1.default)(attributes.hasOwnProperty(attr), `非法的属性${attr}`);
|
(0, assert_1.default)(attributes.hasOwnProperty(attr), `非法的属性${attr}`);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import SqlString from 'sqlstring';
|
import SqlString from 'sqlstring';
|
||||||
import { assign, cloneDeep, difference, identity, intersection, keys, set } from 'lodash';
|
import { assign, cloneDeep, difference, identity, intersection, keys, set } from 'lodash';
|
||||||
import { Attribute, EntityDict, EXPRESSION_PREFIX, Index, OperateOption,
|
import {
|
||||||
|
Attribute, EntityDict, EXPRESSION_PREFIX, Index, OperateOption,
|
||||||
Q_FullTextValue, Ref, RefOrExpression, SelectOption, StorageSchema, SubQueryPredicateMetadata,
|
Q_FullTextValue, Ref, RefOrExpression, SelectOption, StorageSchema, SubQueryPredicateMetadata,
|
||||||
TriggerDataAttribute, CreateAtAttribute, UpdateAtAttribute, DeleteAtAttribute, SeqAttribute, TriggerUuidAttribute } from "oak-domain/lib/types";
|
TriggerDataAttribute, CreateAtAttribute, UpdateAtAttribute, DeleteAtAttribute, SeqAttribute, TriggerUuidAttribute
|
||||||
|
} from "oak-domain/lib/types";
|
||||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||||
import { DataType } from "oak-domain/lib/types/schema/DataTypes";
|
import { DataType } from "oak-domain/lib/types/schema/DataTypes";
|
||||||
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
||||||
|
|
@ -80,7 +82,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
||||||
attributes: [{
|
attributes: [{
|
||||||
name: TriggerUuidAttribute,
|
name: TriggerUuidAttribute,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// 增加外键等相关属性上的索引
|
// 增加外键等相关属性上的索引
|
||||||
|
|
@ -788,44 +790,62 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const fk = foreignKey || 'entityId';
|
const fk = foreignKey || 'entityId';
|
||||||
const joinFilter = {
|
|
||||||
$expr12: {
|
// 对in和not in优化,不要用exists查询
|
||||||
$eq: [
|
if (['in', 'not in'].includes(predicate)) {
|
||||||
{
|
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
||||||
'#attr': fk,
|
data: {
|
||||||
},
|
[fk]: 1,
|
||||||
{
|
},
|
||||||
'#refId': refAlia2,
|
filter: filter2[attr]
|
||||||
'#refAttr': 'id',
|
}, currentNumber, filterRefAlias, option);
|
||||||
}
|
|
||||||
],
|
currentNumber = ct2;
|
||||||
}
|
whereText += `(${refAlia2}.id ${predicate} (${stmt}))`;
|
||||||
};
|
}
|
||||||
if (!foreignKey) {
|
else {
|
||||||
Object.assign(joinFilter, {
|
/**
|
||||||
entity: entity2,
|
* 只剩下all/not all
|
||||||
});
|
* 翻译成键值不等条件下的not exist/exist
|
||||||
|
*/
|
||||||
|
const joinFilter = {
|
||||||
|
$expr83: {
|
||||||
|
[['all', 'not all'].includes(predicate) ? '$ne' : '$eq']: [
|
||||||
|
{
|
||||||
|
'#attr': fk,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'#refId': refAlia2,
|
||||||
|
'#refAttr': 'id',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!foreignKey) {
|
||||||
|
Object.assign(joinFilter, {
|
||||||
|
entity: entity2,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
},
|
||||||
|
filter: combineFilters(subEntity, this.schema, [joinFilter, filter2[attr]]),
|
||||||
|
indexFrom: 0,
|
||||||
|
count: 1,
|
||||||
|
}, currentNumber, filterRefAlias, option);
|
||||||
|
currentNumber = ct2;
|
||||||
|
|
||||||
|
const PREDICATE_DICT = {
|
||||||
|
// in 和 not in已经不会命中了(优化到上面的路径中)
|
||||||
|
'in': 'exists',
|
||||||
|
'not in': 'not exists',
|
||||||
|
'all': 'not exists',
|
||||||
|
'not all': 'exists',
|
||||||
|
};
|
||||||
|
whereText += ` ${PREDICATE_DICT[predicate]} (${stmt})`;
|
||||||
}
|
}
|
||||||
const conditionalPredicate = ['all', 'not all'].includes(predicate) ? {
|
|
||||||
$not: filter2[attr],
|
|
||||||
} : filter2[attr];
|
|
||||||
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
},
|
|
||||||
filter: combineFilters(subEntity, this.schema, [joinFilter, conditionalPredicate]),
|
|
||||||
indexFrom: 0,
|
|
||||||
count: 1,
|
|
||||||
}, currentNumber, filterRefAlias, option);
|
|
||||||
currentNumber = ct2;
|
|
||||||
|
|
||||||
const PREDICATE_DICT = {
|
|
||||||
'in': 'exists',
|
|
||||||
'not in': 'not exists',
|
|
||||||
'all': 'not exists',
|
|
||||||
'not all': 'exists',
|
|
||||||
};
|
|
||||||
whereText += ` ${PREDICATE_DICT[predicate]} (${stmt})`;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(attributes.hasOwnProperty(attr), `非法的属性${attr}`);
|
assert(attributes.hasOwnProperty(attr), `非法的属性${attr}`);
|
||||||
|
|
@ -841,7 +861,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
||||||
const predicate = Object.keys(filter2[attr])[0];
|
const predicate = Object.keys(filter2[attr])[0];
|
||||||
assert(predicate.startsWith('$'));
|
assert(predicate.startsWith('$'));
|
||||||
// 对属性上的谓词处理
|
// 对属性上的谓词处理
|
||||||
whereText += ` (\`${alias}\`.\`${attr}\` ${this.translatePredicate(predicate, filter2[attr][predicate], type2)})`;
|
whereText += ` (\`${alias}\`.\`${attr}\` ${this.translatePredicate(predicate, filter2[attr][predicate], type2)})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -859,7 +879,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
||||||
};
|
};
|
||||||
|
|
||||||
const where = translateInner(entity, './', filter);
|
const where = translateInner(entity, './', filter);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
stmt: where,
|
stmt: where,
|
||||||
currentNumber,
|
currentNumber,
|
||||||
|
|
@ -1076,7 +1096,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
||||||
}
|
}
|
||||||
groupByText = as;
|
groupByText = as;
|
||||||
}
|
}
|
||||||
else if (k.startsWith('#')){
|
else if (k.startsWith('#')) {
|
||||||
let { projText: projSubText } = this.translateProjection(entity, (data as any)[k]!, aliasDict, projectionRefAlias, undefined, true);
|
let { projText: projSubText } = this.translateProjection(entity, (data as any)[k]!, aliasDict, projectionRefAlias, undefined, true);
|
||||||
let projSubText2 = '';
|
let projSubText2 = '';
|
||||||
if (k.startsWith('#max')) {
|
if (k.startsWith('#max')) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue