feat: add database indexes for performance optimization
This commit is contained in:
8
drizzle/0002_fancy_forge.sql
Normal file
8
drizzle/0002_fancy_forge.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CREATE INDEX "moderation_cases_user_id_idx" ON "moderation_cases" USING btree ("user_id");--> statement-breakpoint
|
||||||
|
CREATE INDEX "moderation_cases_case_id_idx" ON "moderation_cases" USING btree ("case_id");--> statement-breakpoint
|
||||||
|
CREATE INDEX "transactions_created_at_idx" ON "transactions" USING btree ("created_at");--> statement-breakpoint
|
||||||
|
CREATE INDEX "user_timers_expires_at_idx" ON "user_timers" USING btree ("expires_at");--> statement-breakpoint
|
||||||
|
CREATE INDEX "user_timers_lookup_idx" ON "user_timers" USING btree ("user_id","type","key");--> statement-breakpoint
|
||||||
|
CREATE INDEX "users_username_idx" ON "users" USING btree ("username");--> statement-breakpoint
|
||||||
|
CREATE INDEX "users_balance_idx" ON "users" USING btree ("balance");--> statement-breakpoint
|
||||||
|
CREATE INDEX "users_level_xp_idx" ON "users" USING btree ("level","xp");
|
||||||
1020
drizzle/meta/0002_snapshot.json
Normal file
1020
drizzle/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,13 @@
|
|||||||
"when": 1766606046050,
|
"when": 1766606046050,
|
||||||
"tag": "0001_heavy_thundra",
|
"tag": "0001_heavy_thundra",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 2,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1767716705797,
|
||||||
|
"tag": "0002_fancy_forge",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
43
src/db/indexes.test.ts
Normal file
43
src/db/indexes.test.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { expect, test, describe } from "bun:test";
|
||||||
|
import { postgres } from "../lib/DrizzleClient";
|
||||||
|
|
||||||
|
describe("Database Indexes", () => {
|
||||||
|
test("should have indexes on users table", async () => {
|
||||||
|
const result = await postgres`
|
||||||
|
SELECT indexname FROM pg_indexes
|
||||||
|
WHERE tablename = 'users'
|
||||||
|
`;
|
||||||
|
const indexNames = result.map(r => r.indexname);
|
||||||
|
expect(indexNames).toContain("users_balance_idx");
|
||||||
|
expect(indexNames).toContain("users_level_xp_idx");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should have index on transactions table", async () => {
|
||||||
|
const result = await postgres`
|
||||||
|
SELECT indexname FROM pg_indexes
|
||||||
|
WHERE tablename = 'transactions'
|
||||||
|
`;
|
||||||
|
const indexNames = result.map(r => r.indexname);
|
||||||
|
expect(indexNames).toContain("transactions_created_at_idx");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should have indexes on moderation_cases table", async () => {
|
||||||
|
const result = await postgres`
|
||||||
|
SELECT indexname FROM pg_indexes
|
||||||
|
WHERE tablename = 'moderation_cases'
|
||||||
|
`;
|
||||||
|
const indexNames = result.map(r => r.indexname);
|
||||||
|
expect(indexNames).toContain("moderation_cases_user_id_idx");
|
||||||
|
expect(indexNames).toContain("moderation_cases_case_id_idx");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should have indexes on user_timers table", async () => {
|
||||||
|
const result = await postgres`
|
||||||
|
SELECT indexname FROM pg_indexes
|
||||||
|
WHERE tablename = 'user_timers'
|
||||||
|
`;
|
||||||
|
const indexNames = result.map(r => r.indexname);
|
||||||
|
expect(indexNames).toContain("user_timers_expires_at_idx");
|
||||||
|
expect(indexNames).toContain("user_timers_lookup_idx");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
text,
|
text,
|
||||||
integer,
|
integer,
|
||||||
primaryKey,
|
primaryKey,
|
||||||
|
index,
|
||||||
bigserial,
|
bigserial,
|
||||||
check
|
check
|
||||||
} from 'drizzle-orm/pg-core';
|
} from 'drizzle-orm/pg-core';
|
||||||
@@ -41,7 +42,11 @@ export const users = pgTable('users', {
|
|||||||
settings: jsonb('settings').default({}),
|
settings: jsonb('settings').default({}),
|
||||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
|
||||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),
|
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),
|
||||||
});
|
}, (table) => [
|
||||||
|
index('users_username_idx').on(table.username),
|
||||||
|
index('users_balance_idx').on(table.balance),
|
||||||
|
index('users_level_xp_idx').on(table.level, table.xp),
|
||||||
|
]);
|
||||||
|
|
||||||
// 3. Items
|
// 3. Items
|
||||||
export const items = pgTable('items', {
|
export const items = pgTable('items', {
|
||||||
@@ -82,7 +87,9 @@ export const transactions = pgTable('transactions', {
|
|||||||
type: varchar('type', { length: 50 }).notNull(),
|
type: varchar('type', { length: 50 }).notNull(),
|
||||||
description: text('description'),
|
description: text('description'),
|
||||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
|
||||||
});
|
}, (table) => [
|
||||||
|
index('transactions_created_at_idx').on(table.createdAt),
|
||||||
|
]);
|
||||||
|
|
||||||
export const itemTransactions = pgTable('item_transactions', {
|
export const itemTransactions = pgTable('item_transactions', {
|
||||||
id: bigserial('id', { mode: 'bigint' }).primaryKey(),
|
id: bigserial('id', { mode: 'bigint' }).primaryKey(),
|
||||||
@@ -129,7 +136,9 @@ export const userTimers = pgTable('user_timers', {
|
|||||||
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
||||||
metadata: jsonb('metadata').default({}), // Store channelId, specific buff amounts, etc.
|
metadata: jsonb('metadata').default({}), // Store channelId, specific buff amounts, etc.
|
||||||
}, (table) => [
|
}, (table) => [
|
||||||
primaryKey({ columns: [table.userId, table.type, table.key] })
|
primaryKey({ columns: [table.userId, table.type, table.key] }),
|
||||||
|
index('user_timers_expires_at_idx').on(table.expiresAt),
|
||||||
|
index('user_timers_lookup_idx').on(table.userId, table.type, table.key),
|
||||||
]);
|
]);
|
||||||
// 9. Lootdrops
|
// 9. Lootdrops
|
||||||
export const lootdrops = pgTable('lootdrops', {
|
export const lootdrops = pgTable('lootdrops', {
|
||||||
@@ -158,7 +167,10 @@ export const moderationCases = pgTable('moderation_cases', {
|
|||||||
resolvedAt: timestamp('resolved_at', { withTimezone: true }),
|
resolvedAt: timestamp('resolved_at', { withTimezone: true }),
|
||||||
resolvedBy: bigint('resolved_by', { mode: 'bigint' }),
|
resolvedBy: bigint('resolved_by', { mode: 'bigint' }),
|
||||||
resolvedReason: text('resolved_reason'),
|
resolvedReason: text('resolved_reason'),
|
||||||
});
|
}, (table) => [
|
||||||
|
index('moderation_cases_user_id_idx').on(table.userId),
|
||||||
|
index('moderation_cases_case_id_idx').on(table.caseId),
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user