优化了in/not in的SQL语句
This commit is contained in:
parent
c789457f96
commit
09715010e4
|
|
@ -617,43 +617,58 @@ class SqlTranslator {
|
|||
});
|
||||
}
|
||||
const fk = foreignKey || 'entityId';
|
||||
const joinFilter = {
|
||||
$expr12: {
|
||||
$eq: [
|
||||
{
|
||||
'#attr': fk,
|
||||
},
|
||||
{
|
||||
'#refId': refAlia2,
|
||||
'#refAttr': 'id',
|
||||
}
|
||||
],
|
||||
}
|
||||
};
|
||||
if (!foreignKey) {
|
||||
Object.assign(joinFilter, {
|
||||
entity: entity2,
|
||||
});
|
||||
// 对in和not in优化,不要用exists查询
|
||||
if (['in', 'not in'].includes(predicate)) {
|
||||
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
||||
data: {
|
||||
[fk]: 1,
|
||||
},
|
||||
filter: filter2[attr]
|
||||
}, currentNumber, filterRefAlias, option);
|
||||
currentNumber = ct2;
|
||||
whereText += `(${refAlia2}.id ${predicate} (${stmt}))`;
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* 只剩下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: (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 {
|
||||
(0, assert_1.default)(attributes.hasOwnProperty(attr), `非法的属性${attr}`);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import assert from 'assert';
|
||||
import SqlString from 'sqlstring';
|
||||
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,
|
||||
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 { DataType } from "oak-domain/lib/types/schema/DataTypes";
|
||||
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
||||
|
|
@ -80,7 +82,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
|||
attributes: [{
|
||||
name: TriggerUuidAttribute,
|
||||
}]
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// 增加外键等相关属性上的索引
|
||||
|
|
@ -788,44 +790,62 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
|||
});
|
||||
}
|
||||
const fk = foreignKey || 'entityId';
|
||||
const joinFilter = {
|
||||
$expr12: {
|
||||
$eq: [
|
||||
{
|
||||
'#attr': fk,
|
||||
},
|
||||
{
|
||||
'#refId': refAlia2,
|
||||
'#refAttr': 'id',
|
||||
}
|
||||
],
|
||||
}
|
||||
};
|
||||
if (!foreignKey) {
|
||||
Object.assign(joinFilter, {
|
||||
entity: entity2,
|
||||
});
|
||||
|
||||
// 对in和not in优化,不要用exists查询
|
||||
if (['in', 'not in'].includes(predicate)) {
|
||||
const { stmt, currentNumber: ct2 } = this.translateSelectInner(subEntity, {
|
||||
data: {
|
||||
[fk]: 1,
|
||||
},
|
||||
filter: filter2[attr]
|
||||
}, currentNumber, filterRefAlias, option);
|
||||
|
||||
currentNumber = ct2;
|
||||
whereText += `(${refAlia2}.id ${predicate} (${stmt}))`;
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* 只剩下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 {
|
||||
assert(attributes.hasOwnProperty(attr), `非法的属性${attr}`);
|
||||
|
|
@ -841,7 +861,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
|||
const predicate = Object.keys(filter2[attr])[0];
|
||||
assert(predicate.startsWith('$'));
|
||||
// 对属性上的谓词处理
|
||||
whereText += ` (\`${alias}\`.\`${attr}\` ${this.translatePredicate(predicate, filter2[attr][predicate], type2)})`;
|
||||
whereText += ` (\`${alias}\`.\`${attr}\` ${this.translatePredicate(predicate, filter2[attr][predicate], type2)})`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -859,7 +879,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
|||
};
|
||||
|
||||
const where = translateInner(entity, './', filter);
|
||||
|
||||
|
||||
return {
|
||||
stmt: where,
|
||||
currentNumber,
|
||||
|
|
@ -1076,7 +1096,7 @@ export abstract class SqlTranslator<ED extends EntityDict & BaseEntityDict> {
|
|||
}
|
||||
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 projSubText2 = '';
|
||||
if (k.startsWith('#max')) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue