feat: optimize database indexes
This commit is contained in:
@@ -31,36 +31,29 @@ const dbInit = {
|
||||
await this.v3_0DB(c);
|
||||
await this.v3_1DB(c);
|
||||
await this.v3_2DB(c);
|
||||
await this.v3_3DB(c);
|
||||
await settingService.refresh(c);
|
||||
return c.text('success');
|
||||
},
|
||||
|
||||
async v3_3DB(c) {
|
||||
const oauthSwitchFields = [
|
||||
'linuxdo_switch', 'github_switch', 'google_switch',
|
||||
];
|
||||
for (const field of oauthSwitchFields) {
|
||||
try {
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN ${field} INTEGER NOT NULL DEFAULT 1;`).run();
|
||||
} catch (e) {
|
||||
console.warn(`跳过字段:${e.message}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async v3_2DB(c) {
|
||||
const oauthFields = [
|
||||
'linuxdo_client_id', 'linuxdo_client_secret',
|
||||
'github_client_id', 'github_client_secret',
|
||||
'google_client_id', 'google_client_secret',
|
||||
];
|
||||
for (const field of oauthFields) {
|
||||
try {
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN ${field} TEXT NOT NULL DEFAULT '';`).run();
|
||||
} catch (e) {
|
||||
console.warn(`跳过字段:${e.message}`);
|
||||
}
|
||||
try {
|
||||
await c.env.db.batch([
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN linuxdo_client_id TEXT NOT NULL DEFAULT '';`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN linuxdo_client_secret TEXT NOT NULL DEFAULT '';`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN github_client_id TEXT NOT NULL DEFAULT '';`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN github_client_secret TEXT NOT NULL DEFAULT '';`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN google_client_id TEXT NOT NULL DEFAULT '';`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN google_client_secret TEXT NOT NULL DEFAULT '';`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN linuxdo_switch INTEGER NOT NULL DEFAULT 1;`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN github_switch INTEGER NOT NULL DEFAULT 1;`),
|
||||
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN google_switch INTEGER NOT NULL DEFAULT 1;`),
|
||||
await c.env.db.prepare(`CREATE INDEX IF NOT EXISTS idx_email_list_user ON email(user_id, type, is_del, email_id)`),
|
||||
await c.env.db.prepare(`CREATE INDEX IF NOT EXISTS idx_email_list_account ON email(user_id, account_id, type, is_del, email_id)`),
|
||||
await c.env.db.prepare(`CREATE INDEX IF NOT EXISTS idx_star_user_email ON star(user_id, email_id)`),
|
||||
await c.env.db.prepare(`CREATE INDEX IF NOT EXISTS idx_star_email_user ON star(email_id, user_id)`)
|
||||
]);
|
||||
} catch (e) {
|
||||
console.warn(`跳过字段:${e.message}`);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ const emailService = {
|
||||
let { emailId, type, accountId, size, timeSort, allReceive } = params;
|
||||
|
||||
size = Number(size);
|
||||
emailId = Number(emailId);
|
||||
emailId = Number(emailId) || 0;
|
||||
timeSort = Number(timeSort);
|
||||
accountId = Number(accountId);
|
||||
allReceive = Number(allReceive);
|
||||
@@ -39,21 +39,14 @@ const emailService = {
|
||||
size = 50;
|
||||
}
|
||||
|
||||
if (!emailId) {
|
||||
|
||||
if (timeSort) {
|
||||
emailId = 0;
|
||||
} else {
|
||||
emailId = 9999999999;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isNaN(allReceive)) {
|
||||
let accountRow = await accountService.selectById(c, accountId);
|
||||
allReceive = accountRow.allReceive;
|
||||
}
|
||||
|
||||
const filters = this.emailListFilters({ userId, accountId, type, allReceive, emailId, timeSort });
|
||||
const countFilters = this.emailListFilters({ userId, accountId, type, allReceive, withCursor: false });
|
||||
|
||||
const query = orm(c)
|
||||
.select({
|
||||
...email,
|
||||
@@ -66,20 +59,12 @@ const emailService = {
|
||||
eq(star.emailId, email.emailId),
|
||||
eq(star.userId, userId)
|
||||
)
|
||||
).leftJoin(
|
||||
)
|
||||
.innerJoin(
|
||||
account,
|
||||
eq(account.accountId, email.accountId)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
allReceive ? eq(1,1) : eq(email.accountId, accountId),
|
||||
eq(email.userId, userId),
|
||||
timeSort ? gt(email.emailId, emailId) : lt(email.emailId, emailId),
|
||||
eq(email.type, type),
|
||||
eq(email.isDel, isDel.NORMAL),
|
||||
eq(account.isDel, isDel.NORMAL)
|
||||
)
|
||||
);
|
||||
.where(and(...filters));
|
||||
|
||||
if (timeSort) {
|
||||
query.orderBy(asc(email.emailId));
|
||||
@@ -90,26 +75,19 @@ const emailService = {
|
||||
const listQuery = query.limit(size).all();
|
||||
|
||||
const totalQuery = orm(c).select({ total: count() }).from(email)
|
||||
.leftJoin(
|
||||
.innerJoin(
|
||||
account,
|
||||
eq(account.accountId, email.accountId)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
allReceive ? eq(1,1) : eq(email.accountId, accountId),
|
||||
eq(email.userId, userId),
|
||||
eq(email.type, type),
|
||||
eq(email.isDel, isDel.NORMAL),
|
||||
eq(account.isDel, isDel.NORMAL)
|
||||
)
|
||||
).get();
|
||||
.where(and(...countFilters))
|
||||
.get();
|
||||
|
||||
const latestEmailQuery = orm(c).select().from(email).where(
|
||||
and(
|
||||
allReceive ? eq(1,1) : eq(email.accountId, accountId),
|
||||
eq(email.userId, userId),
|
||||
eq(email.type, type),
|
||||
eq(email.isDel, isDel.NORMAL)
|
||||
eq(email.isDel, isDel.NORMAL),
|
||||
allReceive ? undefined : eq(email.accountId, accountId)
|
||||
))
|
||||
.orderBy(desc(email.emailId)).limit(1).get();
|
||||
|
||||
@@ -134,6 +112,71 @@ const emailService = {
|
||||
return { list, total: totalRow.total, latestEmail };
|
||||
},
|
||||
|
||||
emailListFilters({ userId, accountId, type, allReceive, emailId, timeSort, withCursor = true }) {
|
||||
const conditions = [
|
||||
eq(email.userId, userId),
|
||||
eq(email.type, type),
|
||||
eq(email.isDel, isDel.NORMAL),
|
||||
eq(account.isDel, isDel.NORMAL),
|
||||
];
|
||||
if (!allReceive) {
|
||||
conditions.push(eq(email.accountId, accountId));
|
||||
}
|
||||
if (withCursor && emailId) {
|
||||
conditions.push(timeSort ? gt(email.emailId, emailId) : lt(email.emailId, emailId));
|
||||
}
|
||||
return conditions;
|
||||
},
|
||||
|
||||
allEmailListFilters({ emailId, name, subject, accountEmail, userEmail, type, timeSort, withCursor = true }) {
|
||||
const conditions = [];
|
||||
|
||||
if (type === 'send') {
|
||||
conditions.push(eq(email.type, emailConst.type.SEND));
|
||||
}
|
||||
|
||||
if (type === 'receive') {
|
||||
conditions.push(eq(email.type, emailConst.type.RECEIVE));
|
||||
}
|
||||
|
||||
if (type === 'delete') {
|
||||
conditions.push(eq(email.isDel, isDel.DELETE));
|
||||
}
|
||||
|
||||
if (type === 'noone') {
|
||||
conditions.push(eq(email.status, emailConst.status.NOONE));
|
||||
}
|
||||
|
||||
if (userEmail) {
|
||||
conditions.push(sql`${user.email} COLLATE NOCASE LIKE ${'%' + userEmail + '%'}`);
|
||||
}
|
||||
|
||||
if (accountEmail) {
|
||||
conditions.push(
|
||||
or(
|
||||
sql`${email.toEmail} COLLATE NOCASE LIKE ${'%' + accountEmail + '%'}`,
|
||||
sql`${email.sendEmail} COLLATE NOCASE LIKE ${'%' + accountEmail + '%'}`,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
conditions.push(sql`${email.name} COLLATE NOCASE LIKE ${'%' + name + '%'}`);
|
||||
}
|
||||
|
||||
if (subject) {
|
||||
conditions.push(sql`${email.subject} COLLATE NOCASE LIKE ${'%' + subject + '%'}`);
|
||||
}
|
||||
|
||||
conditions.push(ne(email.status, emailConst.status.SAVING));
|
||||
|
||||
if (withCursor && emailId) {
|
||||
conditions.push(timeSort ? gt(email.emailId, emailId) : lt(email.emailId, emailId));
|
||||
}
|
||||
|
||||
return conditions;
|
||||
},
|
||||
|
||||
async delete(c, params, userId) {
|
||||
const { emailIds } = params;
|
||||
const emailIdList = emailIds.split(',').map(Number);
|
||||
@@ -750,7 +793,7 @@ const emailService = {
|
||||
}
|
||||
|
||||
let list = await orm(c).select({...email}).from(email)
|
||||
.leftJoin(
|
||||
.innerJoin(
|
||||
account,
|
||||
eq(account.accountId, email.accountId)
|
||||
)
|
||||
@@ -760,7 +803,7 @@ const emailService = {
|
||||
eq(email.userId, userId),
|
||||
eq(email.isDel, isDel.NORMAL),
|
||||
eq(account.isDel, isDel.NORMAL),
|
||||
allReceive ? eq(1,1) : eq(email.accountId, accountId),
|
||||
allReceive ? undefined : eq(email.accountId, accountId),
|
||||
eq(email.type, emailConst.type.RECEIVE)
|
||||
))
|
||||
.orderBy(desc(email.emailId))
|
||||
@@ -815,81 +858,25 @@ const emailService = {
|
||||
|
||||
size = Number(size);
|
||||
|
||||
emailId = Number(emailId);
|
||||
emailId = Number(emailId) || 0;
|
||||
timeSort = Number(timeSort);
|
||||
|
||||
if (size > 50) {
|
||||
size = 50;
|
||||
}
|
||||
|
||||
if (!emailId) {
|
||||
|
||||
if (timeSort) {
|
||||
emailId = 0;
|
||||
} else {
|
||||
emailId = 9999999999;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const conditions = [];
|
||||
|
||||
if (type === 'send') {
|
||||
conditions.push(eq(email.type, emailConst.type.SEND));
|
||||
}
|
||||
|
||||
if (type === 'receive') {
|
||||
conditions.push(eq(email.type, emailConst.type.RECEIVE));
|
||||
}
|
||||
|
||||
if (type === 'delete') {
|
||||
conditions.push(eq(email.isDel, isDel.DELETE));
|
||||
}
|
||||
|
||||
if (type === 'noone') {
|
||||
conditions.push(eq(email.status, emailConst.status.NOONE));
|
||||
}
|
||||
|
||||
if (userEmail) {
|
||||
conditions.push(sql`${user.email} COLLATE NOCASE LIKE ${'%'+ userEmail + '%'}`);
|
||||
}
|
||||
|
||||
if (accountEmail) {
|
||||
conditions.push(
|
||||
or(
|
||||
sql`${email.toEmail} COLLATE NOCASE LIKE ${'%'+ accountEmail + '%'}`,
|
||||
sql`${email.sendEmail} COLLATE NOCASE LIKE ${'%'+ accountEmail + '%'}`,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (name) {
|
||||
conditions.push(sql`${email.name} COLLATE NOCASE LIKE ${'%'+ name + '%'}`);
|
||||
}
|
||||
|
||||
if (subject) {
|
||||
conditions.push(sql`${email.subject} COLLATE NOCASE LIKE ${'%'+ subject + '%'}`);
|
||||
}
|
||||
|
||||
conditions.push(ne(email.status, emailConst.status.SAVING));
|
||||
|
||||
const countConditions = [...conditions];
|
||||
|
||||
if (timeSort) {
|
||||
conditions.unshift(gt(email.emailId, emailId));
|
||||
} else {
|
||||
conditions.unshift(lt(email.emailId, emailId));
|
||||
}
|
||||
const filters = this.allEmailListFilters({ emailId, name, subject, accountEmail, userEmail, type, timeSort });
|
||||
const countFilters = this.allEmailListFilters({ emailId, name, subject, accountEmail, userEmail, type, timeSort, withCursor: false });
|
||||
|
||||
const query = orm(c).select({ ...email, userEmail: user.email })
|
||||
.from(email)
|
||||
.leftJoin(user, eq(email.userId, user.userId))
|
||||
.where(and(...conditions));
|
||||
.where(and(...filters));
|
||||
|
||||
const queryCount = orm(c).select({ total: count() })
|
||||
.from(email)
|
||||
.leftJoin(user, eq(email.userId, user.userId))
|
||||
.where(and(...countConditions));
|
||||
.where(and(...countFilters));
|
||||
|
||||
if (timeSort) {
|
||||
query.orderBy(asc(email.emailId));
|
||||
|
||||
@@ -42,13 +42,9 @@ const starService = {
|
||||
|
||||
async list(c, params, userId) {
|
||||
let { emailId, size } = params;
|
||||
emailId = Number(emailId);
|
||||
emailId = Number(emailId) || 0;
|
||||
size = Number(size);
|
||||
|
||||
if (!emailId) {
|
||||
emailId = 9999999999;
|
||||
}
|
||||
|
||||
const list = await orm(c).select({
|
||||
isStar: sql`1`.as('isStar'),
|
||||
starId: star.starId
|
||||
@@ -59,7 +55,7 @@ const starService = {
|
||||
and(
|
||||
eq(star.userId, userId),
|
||||
eq(email.isDel, isDel.NORMAL),
|
||||
lt(star.emailId, emailId)))
|
||||
emailId ? lt(star.emailId, emailId) : undefined))
|
||||
.orderBy(desc(star.emailId))
|
||||
.limit(size)
|
||||
.all();
|
||||
|
||||
Reference in New Issue
Block a user