Skip to content

Conversation

@ctrlkk
Copy link
Contributor

@ctrlkk ctrlkk commented Oct 4, 2025


Motivation / 动机

Modifications / 改动点

1、优化了sqlite配置,启用WAL模式和NORMAL,优化并发读写性能,同时增加了一些缓存策略。
2、对话数据,列表显示会话id字段,查询增加会话id条件(会话id指cid,原来的sessionId改为用户id)。
3、对话数据,增加请求打断功能,现在查询时仍然允许输入,如上一次请求没有完成将会被取消。
4、会话管理,搜索框增加输入防抖。

Verification Steps / 验证步骤

Screenshots or Test Results / 运行截图或测试结果

新的sqlite配置中普通查询平均快100ms左右
图片

这是原来的配置
图片

写入性能还未测试

PixPin_2025-10-04_22-21-51

Compatibility & Breaking Changes / 兼容性与破坏性变更

  • 这是一个破坏性变更 (Breaking Change)。/ This is a breaking change.
  • 这不是一个破坏性变更。/ This is NOT a breaking change.

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

Sourcery 总结

优化 SQLite 性能,并提升对话和会话管理页面的交互性和性能。

新功能:

  • 允许通过中止之前的请求来中断正在进行的对话列表查询
  • 为会话搜索输入框添加防抖功能,以减少冗余请求

改进:

  • 启用 SQLite WAL 模式并应用调整后的 PRAGMA 设置 (synchronous, cache_size, temp_store, mmap_size, optimize),以提高并发读/写性能
  • 在对话搜索条件中包含 conversation_id,以支持按对话 ID 过滤
  • 在 ConversationPage 表中显示对话 ID 列,并将 sessionId 列重命名为用户 ID
  • 允许筛选输入项 (platform, type, search) 在加载期间保持可交互状态
  • 将自定义防抖实现替换为 lodash debounce,并为长 ID 添加 text-truncate 样式
Original summary in English

Summary by Sourcery

Optimize SQLite performance and enhance interactivity and performance on the conversation and session management pages.

New Features:

  • Allow interrupting in-flight conversation list queries by aborting previous requests
  • Add debounce to session search input to reduce redundant requests

Enhancements:

  • Enable SQLite WAL mode and apply tuned PRAGMA settings (synchronous, cache_size, temp_store, mmap_size, optimize) to improve concurrent read/write performance
  • Include conversation_id in conversation search criteria to support filtering by conversation ID
  • Display conversation ID column and rename sessionId column to user ID in ConversationPage table
  • Allow filter inputs (platform, type, search) to remain interactive during loading
  • Replace custom debounce implementation with lodash debounce and add text-truncate styling for long IDs

@auto-assign auto-assign bot requested review from advent259141 and anka-afk October 4, 2025 14:26
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嘿,你好——我已经审阅了你的修改——以下是一些反馈:

  • 考虑将 AbortController + fetch 逻辑提取到一个可重用的辅助函数或可组合项中,以避免在多个方法中重复请求中止模式。
  • 将硬编码的 SQLite PRAGMA 设置移动到配置或环境变量中可能会更灵活,这样你就可以在不修改代码的情况下调整性能。
  • 确保新的 cid 列已正确索引并包含在你的后端过滤逻辑中,以防止在按该字段排序或搜索时进行全表扫描。
供 AI 代理使用的提示
请处理此代码审查中的评论:

## 总体评论
- 考虑将 `AbortController + fetch` 逻辑提取到一个可重用的辅助函数或可组合项中,以避免在多个方法中重复请求中止模式。
- 将硬编码的 SQLite PRAGMA 设置移动到配置或环境变量中可能会更灵活,这样你就可以在不修改代码的情况下调整性能。
- 确保新的 `cid` 列已正确索引并包含在你的后端过滤逻辑中,以防止在按该字段排序或搜索时进行全表扫描。

## 个人评论

### 评论 1
<location> `dashboard/src/views/ConversationPage.vue:81` </location>
<code_context>
                             </v-chip>
                         </template>

+                        <template v-slot:item.cid="{ item }">
+                            <span class="text-truncate">{{ item.cid || tm('status.unknown') }}</span>
+                        </template>
</code_context>

<issue_to_address>
**建议:** 截断会话 ID 可能会影响某些工作流的可用性。

考虑添加工具提示或类似功能,允许用户查看或复制完整的 ID。

建议的实现:

```
                        <template v-slot:item.cid="{ item }">
                            <v-tooltip location="top" open-delay="300">
                                <template #activator="{ props }">
                                    <span class="text-truncate" v-bind="props" style="max-width: 180px; display: inline-block;">
                                        {{ item.cid || tm('status.unknown') }}
                                    </span>
                                </template>
                                <div style="display: flex; align-items: center;">
                                    <span style="word-break: break-all;">{{ item.cid || tm('status.unknown') }}</span>
                                    <v-btn
                                        v-if="item.cid"
                                        icon="mdi-content-copy"
                                        size="x-small"
                                        variant="text"
                                        @click.stop="copyToClipboard(item.cid)"
                                        :aria-label="tm('actions.copy')"
                                        class="ml-2"
                                    ></v-btn>
                                </div>
                            </v-tooltip>
                        </template>

```

```
<script>

```

如果你的 `<script>` 部分中尚不存在 `copyToClipboard` 方法,则需要实现它。例如:

```js
methods: {
    copyToClipboard(text) {
        navigator.clipboard.writeText(text);
        this.$toast?.success?.(this.tm('actions.copied')) // or use your preferred notification method
    },
    // ...other methods
}
```

另外,请确保你的项目中可以从 Vuetify 获得 `v-tooltip``v-btn` 组件。
</issue_to_address>

### 评论 2
<location> `astrbot/core/db/sqlite.py:35-40` </location>
<code_context>
         """Initialize the database by creating tables if they do not exist."""
         async with self.engine.begin() as conn:
             await conn.run_sync(SQLModel.metadata.create_all)
+            await conn.execute(text("PRAGMA journal_mode=WAL"))
+            await conn.execute(text("PRAGMA synchronous=NORMAL"))
+            await conn.execute(text("PRAGMA cache_size=50000"))
+            await conn.execute(text("PRAGMA temp_store=MEMORY"))
+            await conn.execute(text("PRAGMA mmap_size=268435456"))
+            await conn.execute(text("PRAGMA optimize"))
             await conn.commit()

</code_context>

<issue_to_address>
**建议(性能):** 应用多个 PRAGMA 语句可能会产生意想不到的副作用。

这些 PRAGMA 设置可能会影响持久性、并发性和内存使用。请审查并记录它们,以确认它们符合部署需求。

```suggestion
            # 将 SQLite 设置为使用预写式日志 (WAL) 以提高并发性。
            # WAL 模式可能会提高性能,但在崩溃时可能会影响持久性。
            await conn.execute(text("PRAGMA journal_mode=WAL"))

            # 将同步模式设置为 NORMAL 以加快写入速度。
            # 与 FULL 相比,这会降低持久性保证。
            await conn.execute(text("PRAGMA synchronous=NORMAL"))

            # 将缓存大小增加到 50000 页(如果页面大小为 1KB,则约为 50MB)。
            # 更高的缓存大小可提高读取性能,但会增加内存使用量。
            await conn.execute(text("PRAGMA cache_size=50000"))

            # 将临时表和索引存储在内存中以加快访问速度。
            # 可能会增加内存使用量。
            await conn.execute(text("PRAGMA temp_store=MEMORY"))

            # 将内存映射 I/O 大小设置为 256MB。
            # 可以提高性能,但会增加内存使用量。
            await conn.execute(text("PRAGMA mmap_size=268435456"))

            # 运行 SQLite 的内部优化器。
            # 可能会提高查询性能。
            await conn.execute(text("PRAGMA optimize"))

            # 注意:这些 PRAGMA 设置会影响持久性、并发性和内存使用。
            # 请在生产环境中使用前审查并确认它们符合部署要求。
```
</issue_to_address>

### 评论 3
<location> `astrbot/core/db/sqlite.py:169` </location>
<code_context>
                         col(ConversationV2.title).ilike(f"%{search_query}%"),
                         col(ConversationV2.content).ilike(f"%{search_query}%"),
                         col(ConversationV2.user_id).ilike(f"%{search_query}%"),
+                        col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),
                     )
                 )
</code_context>

<issue_to_address>
**建议(性能):** 将 conversation_id 添加到搜索中可能会影响查询性能。

监控查询性能,如果需要,请在 conversation_id 上添加索引以防止速度变慢。

建议的实现:

```python
                        col(ConversationV2.title).ilike(f"%{search_query}%"),
                        col(ConversationV2.content).ilike(f"%{search_query}%"),
                        col(ConversationV2.user_id).ilike(f"%{search_query}%"),
                        # 注意:按 conversation_id 搜索可能会影响查询性能。
                        # 监控查询性能,如果需要,请在 conversation_id 上添加索引。
                        col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),

```

```python
                    )
                # 记录查询性能以进行监控
                import logging, time
                logger = logging.getLogger("astrbot.db")
                start_time = time.time()

```

```python
                )
                elapsed = time.time() - start_time
                if elapsed > 1.0:  # 如果查询时间超过 1 秒,则记录
                    logger.warning(f"使用 conversation_id 的搜索查询耗时 {elapsed:.2f}s。如果这种情况很常见,请考虑添加索引。")

```
</issue_to_address>

Sourcery 对开源项目免费 - 如果您喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进你的评论。
Original comment in English

Hey there - I've reviewed your changes - here's some feedback:

  • Consider extracting the AbortController + fetch logic into a reusable helper or composable to avoid duplicating the request-abort pattern across multiple methods.
  • It might be more flexible to move the hardcoded SQLite PRAGMA settings into configuration or environment variables so you can tune performance without modifying code.
  • Ensure the new cid column is properly indexed and included in your backend filtering logic to prevent full table scans when sorting or searching by that field.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the AbortController + fetch logic into a reusable helper or composable to avoid duplicating the request-abort pattern across multiple methods.
- It might be more flexible to move the hardcoded SQLite PRAGMA settings into configuration or environment variables so you can tune performance without modifying code.
- Ensure the new `cid` column is properly indexed and included in your backend filtering logic to prevent full table scans when sorting or searching by that field.

## Individual Comments

### Comment 1
<location> `dashboard/src/views/ConversationPage.vue:81` </location>
<code_context>
                             </v-chip>
                         </template>

+                        <template v-slot:item.cid="{ item }">
+                            <span class="text-truncate">{{ item.cid || tm('status.unknown') }}</span>
+                        </template>
</code_context>

<issue_to_address>
**suggestion:** Truncating the conversation ID may hinder usability for some workflows.

Consider adding a tooltip or similar feature to allow users to view or copy the full ID.

Suggested implementation:

```
                        <template v-slot:item.cid="{ item }">
                            <v-tooltip location="top" open-delay="300">
                                <template #activator="{ props }">
                                    <span class="text-truncate" v-bind="props" style="max-width: 180px; display: inline-block;">
                                        {{ item.cid || tm('status.unknown') }}
                                    </span>
                                </template>
                                <div style="display: flex; align-items: center;">
                                    <span style="word-break: break-all;">{{ item.cid || tm('status.unknown') }}</span>
                                    <v-btn
                                        v-if="item.cid"
                                        icon="mdi-content-copy"
                                        size="x-small"
                                        variant="text"
                                        @click.stop="copyToClipboard(item.cid)"
                                        :aria-label="tm('actions.copy')"
                                        class="ml-2"
                                    ></v-btn>
                                </div>
                            </v-tooltip>
                        </template>

```

```
<script>

```

You will need to implement the `copyToClipboard` method in your `<script>` section if it does not already exist. For example:

```js
methods: {
    copyToClipboard(text) {
        navigator.clipboard.writeText(text);
        this.$toast?.success?.(this.tm('actions.copied')) // or use your preferred notification method
    },
    // ...other methods
}
```

Also, ensure that the `v-tooltip` and `v-btn` components are available from Vuetify in your project.
</issue_to_address>

### Comment 2
<location> `astrbot/core/db/sqlite.py:35-40` </location>
<code_context>
         """Initialize the database by creating tables if they do not exist."""
         async with self.engine.begin() as conn:
             await conn.run_sync(SQLModel.metadata.create_all)
+            await conn.execute(text("PRAGMA journal_mode=WAL"))
+            await conn.execute(text("PRAGMA synchronous=NORMAL"))
+            await conn.execute(text("PRAGMA cache_size=50000"))
+            await conn.execute(text("PRAGMA temp_store=MEMORY"))
+            await conn.execute(text("PRAGMA mmap_size=268435456"))
+            await conn.execute(text("PRAGMA optimize"))
             await conn.commit()

</code_context>

<issue_to_address>
**suggestion (performance):** Applying multiple PRAGMA statements may have unintended side effects.

These PRAGMA settings may impact durability, concurrency, and memory usage. Please review and document them to confirm they meet deployment needs.

```suggestion
            # Set SQLite to use Write-Ahead Logging for improved concurrency.
            # WAL mode may increase performance but can affect durability in case of crashes.
            await conn.execute(text("PRAGMA journal_mode=WAL"))

            # Set synchronous mode to NORMAL for faster writes.
            # This reduces durability guarantees compared to FULL.
            await conn.execute(text("PRAGMA synchronous=NORMAL"))

            # Increase cache size to 50000 pages (~50MB if page size is 1KB).
            # Higher cache size improves read performance but increases memory usage.
            await conn.execute(text("PRAGMA cache_size=50000"))

            # Store temporary tables and indices in memory for faster access.
            # May increase memory usage.
            await conn.execute(text("PRAGMA temp_store=MEMORY"))

            # Set memory-mapped I/O size to 256MB.
            # Can improve performance but increases memory usage.
            await conn.execute(text("PRAGMA mmap_size=268435456"))

            # Run SQLite's internal optimizer.
            # May improve query performance.
            await conn.execute(text("PRAGMA optimize"))

            # NOTE: These PRAGMA settings impact durability, concurrency, and memory usage.
            # Please review and confirm they meet deployment requirements before use in production.
```
</issue_to_address>

### Comment 3
<location> `astrbot/core/db/sqlite.py:169` </location>
<code_context>
                         col(ConversationV2.title).ilike(f"%{search_query}%"),
                         col(ConversationV2.content).ilike(f"%{search_query}%"),
                         col(ConversationV2.user_id).ilike(f"%{search_query}%"),
+                        col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),
                     )
                 )
</code_context>

<issue_to_address>
**suggestion (performance):** Adding conversation_id to search may impact query performance.

Monitor query performance and add an index on conversation_id if needed to prevent slowdowns.

Suggested implementation:

```python
                        col(ConversationV2.title).ilike(f"%{search_query}%"),
                        col(ConversationV2.content).ilike(f"%{search_query}%"),
                        col(ConversationV2.user_id).ilike(f"%{search_query}%"),
                        # NOTE: Searching by conversation_id may impact query performance.
                        # Monitor query performance and add an index on conversation_id if needed.
                        col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),

```

```python
                    )
                # Log query performance for monitoring
                import logging, time
                logger = logging.getLogger("astrbot.db")
                start_time = time.time()

```

```python
                )
                elapsed = time.time() - start_time
                if elapsed > 1.0:  # Log if query takes longer than 1 second
                    logger.warning(f"Search query with conversation_id took {elapsed:.2f}s. Consider adding an index if this is common.")

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 35 to 40
await conn.execute(text("PRAGMA journal_mode=WAL"))
await conn.execute(text("PRAGMA synchronous=NORMAL"))
await conn.execute(text("PRAGMA cache_size=50000"))
await conn.execute(text("PRAGMA temp_store=MEMORY"))
await conn.execute(text("PRAGMA mmap_size=268435456"))
await conn.execute(text("PRAGMA optimize"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议(性能): 应用多个 PRAGMA 语句可能会产生意想不到的副作用。

这些 PRAGMA 设置可能会影响持久性、并发性和内存使用。请审查并记录它们,以确认它们符合部署需求。

Suggested change
await conn.execute(text("PRAGMA journal_mode=WAL"))
await conn.execute(text("PRAGMA synchronous=NORMAL"))
await conn.execute(text("PRAGMA cache_size=50000"))
await conn.execute(text("PRAGMA temp_store=MEMORY"))
await conn.execute(text("PRAGMA mmap_size=268435456"))
await conn.execute(text("PRAGMA optimize"))
# 将 SQLite 设置为使用预写式日志 (WAL) 以提高并发性。
# WAL 模式可能会提高性能,但在崩溃时可能会影响持久性。
await conn.execute(text("PRAGMA journal_mode=WAL"))
# 将同步模式设置为 NORMAL 以加快写入速度。
# 与 FULL 相比,这会降低持久性保证。
await conn.execute(text("PRAGMA synchronous=NORMAL"))
# 将缓存大小增加到 50000 页(如果页面大小为 1KB,则约为 50MB)。
# 更高的缓存大小可提高读取性能,但会增加内存使用量。
await conn.execute(text("PRAGMA cache_size=50000"))
# 将临时表和索引存储在内存中以加快访问速度。
# 可能会增加内存使用量。
await conn.execute(text("PRAGMA temp_store=MEMORY"))
# 将内存映射 I/O 大小设置为 256MB。
# 可以提高性能,但会增加内存使用量。
await conn.execute(text("PRAGMA mmap_size=268435456"))
# 运行 SQLite 的内部优化器。
# 可能会提高查询性能。
await conn.execute(text("PRAGMA optimize"))
# 注意:这些 PRAGMA 设置会影响持久性、并发性和内存使用。
# 请在生产环境中使用前审查并确认它们符合部署要求。
Original comment in English

suggestion (performance): Applying multiple PRAGMA statements may have unintended side effects.

These PRAGMA settings may impact durability, concurrency, and memory usage. Please review and document them to confirm they meet deployment needs.

Suggested change
await conn.execute(text("PRAGMA journal_mode=WAL"))
await conn.execute(text("PRAGMA synchronous=NORMAL"))
await conn.execute(text("PRAGMA cache_size=50000"))
await conn.execute(text("PRAGMA temp_store=MEMORY"))
await conn.execute(text("PRAGMA mmap_size=268435456"))
await conn.execute(text("PRAGMA optimize"))
# Set SQLite to use Write-Ahead Logging for improved concurrency.
# WAL mode may increase performance but can affect durability in case of crashes.
await conn.execute(text("PRAGMA journal_mode=WAL"))
# Set synchronous mode to NORMAL for faster writes.
# This reduces durability guarantees compared to FULL.
await conn.execute(text("PRAGMA synchronous=NORMAL"))
# Increase cache size to 50000 pages (~50MB if page size is 1KB).
# Higher cache size improves read performance but increases memory usage.
await conn.execute(text("PRAGMA cache_size=50000"))
# Store temporary tables and indices in memory for faster access.
# May increase memory usage.
await conn.execute(text("PRAGMA temp_store=MEMORY"))
# Set memory-mapped I/O size to 256MB.
# Can improve performance but increases memory usage.
await conn.execute(text("PRAGMA mmap_size=268435456"))
# Run SQLite's internal optimizer.
# May improve query performance.
await conn.execute(text("PRAGMA optimize"))
# NOTE: These PRAGMA settings impact durability, concurrency, and memory usage.
# Please review and confirm they meet deployment requirements before use in production.

col(ConversationV2.title).ilike(f"%{search_query}%"),
col(ConversationV2.content).ilike(f"%{search_query}%"),
col(ConversationV2.user_id).ilike(f"%{search_query}%"),
col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议(性能): 将 conversation_id 添加到搜索中可能会影响查询性能。

监控查询性能,如果需要,请在 conversation_id 上添加索引以防止速度变慢。

建议的实现:

                        col(ConversationV2.title).ilike(f"%{search_query}%"),
                        col(ConversationV2.content).ilike(f"%{search_query}%"),
                        col(ConversationV2.user_id).ilike(f"%{search_query}%"),
                        # 注意:按 conversation_id 搜索可能会影响查询性能。
                        # 监控查询性能,如果需要,请在 conversation_id 上添加索引。
                        col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),
                    )
                # 记录查询性能以进行监控
                import logging, time
                logger = logging.getLogger("astrbot.db")
                start_time = time.time()
                )
                elapsed = time.time() - start_time
                if elapsed > 1.0:  # 如果查询时间超过 1 秒,则记录
                    logger.warning(f"使用 conversation_id 的搜索查询耗时 {elapsed:.2f}s。如果这种情况很常见,请考虑添加索引。")
Original comment in English

suggestion (performance): Adding conversation_id to search may impact query performance.

Monitor query performance and add an index on conversation_id if needed to prevent slowdowns.

Suggested implementation:

                        col(ConversationV2.title).ilike(f"%{search_query}%"),
                        col(ConversationV2.content).ilike(f"%{search_query}%"),
                        col(ConversationV2.user_id).ilike(f"%{search_query}%"),
                        # NOTE: Searching by conversation_id may impact query performance.
                        # Monitor query performance and add an index on conversation_id if needed.
                        col(ConversationV2.conversation_id).ilike(f"%{search_query}%"),
                    )
                # Log query performance for monitoring
                import logging, time
                logger = logging.getLogger("astrbot.db")
                start_time = time.time()
                )
                elapsed = time.time() - start_time
                if elapsed > 1.0:  # Log if query takes longer than 1 second
                    logger.warning(f"Search query with conversation_id took {elapsed:.2f}s. Consider adding an index if this is common.")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant