mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
fix: partial index on events announced (#4856)
## About the changes Add partial index on events by announced. This should help avoid `Seq Scan on events` when the majority of events are announced=true --- Co-authored-by: Ivar Østhus <ivar@getunleash.io> Co-authored-by: Gard Rimestad <gard@getunleash.io>
This commit is contained in:
parent
19053cd75c
commit
f9c3259083
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: 18.17
|
||||
cache: 'yarn'
|
||||
- run: yarn
|
||||
- run: yarn build:frontend
|
||||
|
2
.github/workflows/build_coverage.yaml
vendored
2
.github/workflows/build_coverage.yaml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: 18.17
|
||||
cache: 'yarn'
|
||||
- run: yarn
|
||||
- run: yarn build:frontend
|
||||
|
2
.github/workflows/build_prs.yaml
vendored
2
.github/workflows/build_prs.yaml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: 18.17
|
||||
cache: 'yarn'
|
||||
- run: yarn install --frozen-lockfile --ignore-scripts
|
||||
- run: yarn lint
|
||||
|
2
.github/workflows/build_prs_jest_report.yaml
vendored
2
.github/workflows/build_prs_jest_report.yaml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 18.17
|
||||
cache: 'yarn'
|
||||
- name: Tests on 18.x
|
||||
id: coverage
|
||||
|
2
.github/workflows/build_prs_test_report.yaml
vendored
2
.github/workflows/build_prs_test_report.yaml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
- name: Use Node.js 18
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 18.17
|
||||
cache: 'yarn'
|
||||
- run: yarn install --frozen-lockfile --ignore-scripts
|
||||
- run: yarn build:backend
|
||||
|
@ -30,7 +30,7 @@ jobs:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: 18.17
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
current/yarn.lock
|
||||
|
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
- name: Setup to npm
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
node-version: 18.17
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: 'yarn'
|
||||
- name: Build
|
||||
|
@ -19,6 +19,7 @@ test('Trying to get events if db fails should yield empty list', async () => {
|
||||
const store = new EventStore(db, getLogger);
|
||||
const events = await store.getEvents();
|
||||
expect(events.length).toBe(0);
|
||||
await db.destroy();
|
||||
});
|
||||
|
||||
test('Trying to get events by name if db fails should yield empty list', async () => {
|
||||
@ -29,39 +30,25 @@ test('Trying to get events by name if db fails should yield empty list', async (
|
||||
const events = await store.searchEvents({ type: 'application-created' });
|
||||
expect(events).toBeTruthy();
|
||||
expect(events.length).toBe(0);
|
||||
await db.destroy();
|
||||
});
|
||||
|
||||
test.each([
|
||||
{
|
||||
createdAt: formatRFC3339(subHours(new Date(), 1)),
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
createdAt: formatRFC3339(subHours(new Date(), 23)),
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
createdAt: formatRFC3339(subHours(new Date(), 25)),
|
||||
expectedCount: 0,
|
||||
},
|
||||
])(
|
||||
'Find unnanounced events is capped to last 24hs',
|
||||
async ({ createdAt, expectedCount }) => {
|
||||
const db = await dbInit('events_test', getLogger);
|
||||
const type = 'application-created' as const;
|
||||
const insertQuery = db.rawDatabase('events');
|
||||
await insertQuery
|
||||
.insert({
|
||||
type,
|
||||
created_at: createdAt,
|
||||
created_by: 'a test',
|
||||
data: { name: 'test', createdAt },
|
||||
})
|
||||
.returning(['id']);
|
||||
// We might want to cap this to 500 and this test can help checking that
|
||||
test('Find unannounced events returns all events', async () => {
|
||||
const db = await dbInit('events_test', getLogger);
|
||||
const type = 'application-created' as const;
|
||||
|
||||
const store = new EventStore(db.rawDatabase, getLogger);
|
||||
const events = await store.setUnannouncedToAnnounced();
|
||||
expect(events).toBeTruthy();
|
||||
expect(events.length).toBe(expectedCount);
|
||||
},
|
||||
);
|
||||
const allEvents = Array.from({ length: 505 }).map((_, i) => ({
|
||||
type,
|
||||
created_at: formatRFC3339(subHours(new Date(), i)),
|
||||
created_by: `test ${i}`,
|
||||
data: { name: 'test', iteration: i },
|
||||
}));
|
||||
await db.rawDatabase('events').insert(allEvents).returning(['id']);
|
||||
|
||||
const store = new EventStore(db.rawDatabase, getLogger);
|
||||
let events = await store.setUnannouncedToAnnounced();
|
||||
expect(events).toBeTruthy();
|
||||
expect(events.length).toBe(505);
|
||||
await db.destroy();
|
||||
});
|
||||
|
@ -12,7 +12,6 @@ import { sharedEventEmitter } from '../util/anyEventEmitter';
|
||||
import { Db } from './db';
|
||||
import { Knex } from 'knex';
|
||||
import EventEmitter from 'events';
|
||||
import { subDays } from 'date-fns';
|
||||
|
||||
const EVENT_COLUMNS = [
|
||||
'id',
|
||||
@ -412,11 +411,7 @@ class EventStore implements IEventStore {
|
||||
const rows = await this.db(TABLE)
|
||||
.update({ announced: true })
|
||||
.where('announced', false)
|
||||
.whereNotNull('announced')
|
||||
.where('created_at', '>', subDays(Date.now(), 1))
|
||||
.returning(EVENT_COLUMNS)
|
||||
.limit(500);
|
||||
|
||||
.returning(EVENT_COLUMNS);
|
||||
return rows.map(this.rowToEvent);
|
||||
}
|
||||
|
||||
|
17
src/migrations/20230927172930-events-announced-index.js
Normal file
17
src/migrations/20230927172930-events-announced-index.js
Normal file
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
exports.up = function (db, callback) {
|
||||
db.runSql(
|
||||
`
|
||||
UPDATE events set announced = false where announced IS NULL;
|
||||
ALTER TABLE events ALTER COLUMN announced SET NOT NULL;
|
||||
ALTER TABLE events ALTER COLUMN announced SET DEFAULT false;
|
||||
CREATE INDEX events_unannounced_idx ON events(announced) WHERE announced = false;
|
||||
`,
|
||||
callback(),
|
||||
);
|
||||
};
|
||||
|
||||
exports.down = function (db, callback) {
|
||||
callback();
|
||||
};
|
Loading…
Reference in New Issue
Block a user