SQL Server: `append_events` does not need the `@inserted` table variable

Đang mở
#619 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

@nmummau đang làm issue này rồi.

Từ ngày 14/10/2026.

  • #621 của @nmummau — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
20/100
Loại issue
Tái cấu trúc
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
sql
Lĩnh vực
databases

Hướng nghiên cứu

The change is in src/SqlServer/src/Eventuous.SqlServer/Scripts/2_AppendEvents.sql: remove the @inserted table variable and get the highest GlobalPosition from SCOPE_IDENTITY(). Check that the nested check_stream procedure runs in a separate scope so it does not change the value. Done means the append and concurrency tests pass and the table variable is gone. Pull request #621 is already open against this issue, so check it before starting.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Summary

append_events writes the new GlobalPosition values into a table variable, only to read their maximum at the end:

DECLARE @inserted TABLE (GlobalPosition BIGINT);

INSERT INTO __schema__.Messages (...)
OUTPUT inserted.GlobalPosition
INTO @inserted (GlobalPosition)
SELECT ... FROM @messages;

...

SELECT @position = (SELECT MAX(GlobalPosition) FROM @inserted);

A statement that writes to a table variable always gets a serial plan, and the OUTPUT ... INTO adds a write to tempdb for each appended event. The procedure can get the same value without the table variable.

How I found it

We capture the actual execution plans from our integration tests and analyze them with Performance Studio. It reports these statements in append_events:

Severity Statement Message
Critical INSERT INTO eventuous.Messages (...) OUTPUT ... INTO @inserted This query modifies a table variable, which forces the entire plan to run single-threaded.
Warning INSERT INTO eventuous.Messages (...) Table variable detected. Table variables lack column-level statistics...
Warning SELECT @position = (SELECT MAX(GlobalPosition) FROM @inserted) Table variable detected.
Warning SELECT @count_messages = COUNT(1) FROM @messages Table variable detected.

To be clear about the impact: an append usually has few events, so a serial plan costs almost nothing. The real gain is a simpler procedure with one less tempdb write per event. The warnings on @messages are not actionable, because @messages is the table-valued parameter and cannot be a #temp table.

Environment: Eventuous 0.17.0, SQL Server 2022. src/SqlServer/src/Eventuous.SqlServer/Scripts/2_AppendEvents.sql on dev has the same code.

Suggested change

GlobalPosition is an IDENTITY column, and the procedure inserts all events in one statement. SCOPE_IDENTITY() returns the last identity value that this statement generated, which is the highest GlobalPosition of the batch. The insert into Streams in check_stream runs in a different scope (a nested procedure), so it does not change the value.

INSERT INTO __schema__.Messages (
    MessageId, MessageType, StreamId, StreamPosition, JsonData, JsonMetadata, Created
)
SELECT
    message_id,
    message_type,
    @stream_id,
    @current_version + CAST(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS INT),
    json_data,
    json_metadata,
    ISNULL(@created, SYSUTCDATETIME())
FROM @messages;

SET @position = SCOPE_IDENTITY();

Then remove the DECLARE @inserted TABLE and the final SELECT @position = (... FROM @inserted). If @messages is empty, SCOPE_IDENTITY() returns NULL, which is the same result that MAX over an empty @inserted gives now.

The existing append and concurrency tests should cover this change. I can open a PR if you agree.

Ngôn ngữ chính
C#
Star
512
Fork
99
Merge trung bình
6 ngày 17 giờ
Pull request đã merge (30 ngày)
2

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của Eventuous/eventuous

Tất cả issue của Eventuous/eventuous

Issue tương tự

Thêm issue về C#

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.