chore: index experiments

This commit is contained in:
John Yeo
2026-03-23 21:08:51 +00:00
parent 0dde2b37fa
commit 3698373e47
2 changed files with 137 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
import { sql } from "drizzle-orm";
import { initDrizzle } from "./experimentEnv";
// Run with `bun run experiments/checkIndexes.ts`
const main = async () => {
const { db } = initDrizzle();
console.log("=== INDEX VALIDITY CHECK ===\n");
const results = await db.execute(sql`
SELECT c.relname, i.indisvalid, i.indisready, i.indislive,
pg_size_pretty(pg_relation_size(c.oid)) as size,
am.amname as type
FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
JOIN pg_am am ON am.oid = c.relam
WHERE c.relname IN (
'idx_referral_codes_internal_customer_id',
'idx_referral_codes_internal_customer_id_v2',
'idx_reward_redemptions_referral_code_id',
'idx_reward_redemptions_referral_code_id_v2',
'idx_customers_processor_gin',
'idx_customers_processor_gin_v2',
'idx_customers_processor_id',
'idx_customers_processor_id_v2'
)
ORDER BY c.relname
`);
if (results.length === 0) {
console.log("No matching indexes found.\n");
}
for (const row of results) {
const r = row as Record<string, unknown>;
const valid = r.indisvalid ? "VALID" : "INVALID";
console.log(
`${valid} | ${r.relname} | type: ${r.type} | size: ${r.size}`,
);
}
process.exit(0);
};
await main();

View File

@@ -0,0 +1,91 @@
import { AppEnv, customers } from "@autumn/shared";
import { and, eq, sql } from "drizzle-orm";
import { initDrizzle, prodTestCustomerId, prodTestOrgId } from "./experimentEnv";
// Run with `bun run experiments/explainGetByStripeId.ts`
const main = async () => {
const orgId = prodTestOrgId;
const env = AppEnv.Live;
const { db } = initDrizzle();
// Grab a real stripe ID from the test customer
const testCus = await db.query.customers.findFirst({
where: and(
eq(customers.id, prodTestCustomerId),
eq(customers.org_id, orgId),
eq(customers.env, env),
),
});
const stripeId = testCus?.processor?.id;
if (!stripeId) {
console.error("Test customer has no processor.id");
process.exit(1);
}
console.log(`Using stripeId: ${stripeId}`);
console.log(`Org: ${orgId} | Env: ${env}\n`);
// ── Check index validity ─────────────────────────────────────────
console.log("=== INDEX VALIDITY ===\n");
const idxValid = await db.execute(sql`
SELECT c.relname, i.indisvalid, i.indisready, i.indislive,
pg_size_pretty(pg_relation_size(c.oid)) as size
FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
WHERE c.relname LIKE '%processor%'
`);
for (const row of idxValid) {
console.log(row);
}
// ── Query with org/env (matches CusService.getByStripeId) ────────
const withOrgEnv = sql`
SELECT * FROM customers
WHERE processor->>'id' = ${stripeId}
AND org_id = ${orgId}
AND env = ${env}
LIMIT 1
`;
console.log("\n=== QUERY: processor->>'id' + org/env ===\n");
const start1 = performance.now();
const result1 = await db.execute(withOrgEnv);
const elapsed1 = performance.now() - start1;
console.log(`Rows: ${result1.length} | Time: ${elapsed1.toFixed(2)}ms\n`);
const explain1 = await db.execute(
sql`EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) ${withOrgEnv}`,
);
for (const row of explain1) {
console.log((row as Record<string, unknown>)["QUERY PLAN"]);
}
// ── Query without org/env (isolate expression index usage) ───────
const withoutOrgEnv = sql`
SELECT * FROM customers
WHERE processor->>'id' = ${stripeId}
LIMIT 1
`;
console.log("\n=== QUERY: processor->>'id' only ===\n");
const start2 = performance.now();
const result2 = await db.execute(withoutOrgEnv);
const elapsed2 = performance.now() - start2;
console.log(`Rows: ${result2.length} | Time: ${elapsed2.toFixed(2)}ms\n`);
const explain2 = await db.execute(
sql`EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) ${withoutOrgEnv}`,
);
for (const row of explain2) {
console.log((row as Record<string, unknown>)["QUERY PLAN"]);
}
process.exit(0);
};
await main();