-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize journal table indices #496
Optimize journal table indices #496
Conversation
|
Method | TagMode | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
---|---|---|---|---|---|---|---|---|
QueryByTag10 | Csv | 2,422.617 ms | 48.3860 ms | 59.4224 ms | - | - | - | 526.11 KB |
QueryByTag100 | Csv | 2,386.379 ms | 28.3730 ms | 25.1520 ms | - | - | - | 1355.14 KB |
QueryByTag1000 | Csv | 2,399.557 ms | 45.5216 ms | 42.5809 ms | 1000.0000 | - | - | 10571.98 KB |
QueryByTag10000 | Csv | 2,514.846 ms | 34.4976 ms | 30.5812 ms | 12000.0000 | 3000.0000 | - | 101477.38 KB |
QueryByTag10 | TagTable | 4.303 ms | 0.1250 ms | 0.3647 ms | 39.0625 | - | - | 347.56 KB |
QueryByTag100 | TagTable | 5.713 ms | 0.1133 ms | 0.2558 ms | 148.4375 | 31.2500 | - | 1240.29 KB |
QueryByTag1000 | TagTable | 23.715 ms | 0.4728 ms | 0.9332 ms | 1281.2500 | 468.7500 | - | 10461.22 KB |
QueryByTag10000 | TagTable | 209.548 ms | 4.1742 ms | 11.4268 ms | 12500.0000 | 3000.0000 | 500.0000 | 101584.23 KB |
This PR benchmark
Method | TagMode | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated |
---|---|---|---|---|---|---|---|---|
QueryByTag10 | Csv | 2,412.107 ms | 44.5888 ms | 41.7083 ms | - | - | - | 527.56 KB |
QueryByTag100 | Csv | 2,456.264 ms | 48.5973 ms | 69.6968 ms | - | - | - | 1355.56 KB |
QueryByTag1000 | Csv | 2,413.896 ms | 42.7739 ms | 37.9180 ms | 1000.0000 | - | - | 10510.35 KB |
QueryByTag10000 | Csv | 2,567.690 ms | 50.4452 ms | 51.8035 ms | 12000.0000 | 3000.0000 | - | 101474.84 KB |
QueryByTag10 | TagTable | 4.054 ms | 0.0805 ms | 0.1662 ms | 39.0625 | - | - | 347.65 KB |
QueryByTag100 | TagTable | 5.465 ms | 0.1061 ms | 0.2307 ms | 148.4375 | 31.2500 | - | 1250.44 KB |
QueryByTag1000 | TagTable | 23.638 ms | 0.4622 ms | 0.7464 ms | 1281.2500 | 562.5000 | - | 10441.6 KB |
QueryByTag10000 | TagTable | 206.246 ms | 4.0650 ms | 7.2256 ms | 12500.0000 | 3000.0000 | 500.0000 | 101577.28 KB |
MS SQL Server dev VS new benchmark comparison
|
PostgreSQL dev VS new benchmark comparison
|
To be honest, the numbers are not good. It gives a fraction of query/read speed at the cost of write speed. |
Yes but these benchmarks aren't testing what happens with a large, pre-existing data set sitting inside the journal and tag tables, which is how 99% of successful Akka.NET applications run given a modest amount of time - so the measurements aren't realistic here. |
Relevant issue: akkadotnet/akka.net#5503 |
Execution Plan BenchmarkingWe've run all of the SQL queries generated by LinqToDb against a SQL Server 2022 running in Docker to observe the actual execution plan for each and these were the findings: ObservationsActor recovery SQL query/* Actor recovery */
DECLARE @take Int -- Int32
SET @take = 1000
DECLARE @persistenceId NVarChar(255) -- String
SET @persistenceId = N'PersistPid1'
DECLARE @fromSequenceNr BigInt -- Int64
SET @fromSequenceNr = 1
DECLARE @toSequenceNr BigInt -- Int64
SET @toSequenceNr = 1000
SELECT TOP (@take)
[r].[ordering],
[r].[created],
[r].[deleted],
[r].[persistence_id],
[r].[sequence_number],
[r].[message],
[r].[manifest],
[r].[identifier],
[r].[writer_uuid]
FROM
[journal] [r]
WHERE
[r].[persistence_id] = @persistenceId AND
[r].[sequence_number] >= @fromSequenceNr AND
[r].[sequence_number] <= @toSequenceNr AND
[r].[deleted] = 0
ORDER BY
[r].[sequence_number] GetHighestOrderingNr SQL Query/* Highest ordering */
SELECT
Max([r].[ordering])
FROM
[journal] [r] CurrentPersistenceIds SQL Query/* CurrentPersistenceIds query */
DECLARE @take Int -- Int32
SET @take = 2147483647
SELECT DISTINCT TOP (@take)
[r].[persistence_id]
FROM
[journal] [r]
WHERE
[r].[deleted] = 0 CurrentPersistenceIds SQL Query With Forced Index/* CurrentPersistenceIds query */
DECLARE @take Int -- Int32
SET @take = 2147483647
SELECT DISTINCT TOP (@take)
[r].[persistence_id]
FROM
[journal] [r]
WITH(INDEX(IX_journal_persistence_id)) -- Force query to use the new index
WHERE
[r].[deleted] = 0 CurrentEventsByTag SQL QueryDECLARE @take Int -- Int32
SET @take = 500
DECLARE @Offset BigInt -- Int64
SET @Offset = 0
DECLARE @MaxOffset BigInt -- Int64
SET @MaxOffset = 0
DECLARE @Tag NVarChar(64) -- String
SET @Tag = N'Tag1'
SELECT TOP (@take)
[x].[ordering],
[x].[created],
[x].[deleted],
[x].[persistence_id],
[x].[sequence_number],
[x].[message],
[x].[manifest],
[x].[identifier],
[x].[writer_uuid],
(
SELECT STRING_AGG([r].[tag], N';')
FROM [tags] [r]
WHERE [r].[ordering_id] = [x].[ordering]
)
FROM
[journal] [x]
LEFT JOIN [tags] [jtr] ON [jtr].[ordering_id] = [x].[ordering]
WHERE
[jtr].[ordering_id] > @Offset AND
[jtr].[ordering_id] <= @MaxOffset AND
[x].[deleted] = 0 AND
[jtr].[tag] = @Tag
ORDER BY
[x].[ordering] FindingsThe new indices was not used in any of the generated SQL statements, and if we force them to use the new indices, it actually hurts performance (5 seconds execution time to 1 minute 25 seconds execution time). ConclusionThe new indices does not help with actor recovery nor persistence query performance, we're dropping this PR and closing the issue. |
Fixes #495
Changes
Optimize journal table query speed by adding indices on (peristence_id) and (persistence_id, ordering)