Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src-tauri/src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use std::sync::Mutex;

/// 当前 Schema 版本号
/// 每次修改表结构时递增,并在 schema.rs 中添加相应的迁移逻辑
pub(crate) const SCHEMA_VERSION: i32 = 6;
pub(crate) const SCHEMA_VERSION: i32 = 7;

/// 安全地序列化 JSON,避免 unwrap panic
pub(crate) fn to_json_string<T: Serialize>(value: &T) -> Result<String, AppError> {
Expand Down
35 changes: 35 additions & 0 deletions src-tauri/src/database/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ impl Database {
Self::migrate_v5_to_v6(conn)?;
Self::set_user_version(conn, 6)?;
}
6 => {
log::info!("迁移数据库从 v6 到 v7(添加性能索引)");
Self::migrate_v6_to_v7(conn)?;
Self::set_user_version(conn, 7)?;
}
_ => {
return Err(AppError::Database(format!(
"未知的数据库版本 {version},无法迁移到 {SCHEMA_VERSION}"
Expand Down Expand Up @@ -1045,6 +1050,36 @@ impl Database {
Ok(())
}

/// v6 -> v7 迁移:添加性能索引
fn migrate_v6_to_v7(conn: &Connection) -> Result<(), AppError> {
if Self::table_exists(conn, "provider_health")? {
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_provider_health_app ON provider_health(app_type)",
[],
)
.map_err(|e| AppError::Database(format!("创建 provider_health app 索引失败: {e}")))?;

conn.execute(
"CREATE INDEX IF NOT EXISTS idx_provider_health_provider ON provider_health(provider_id)",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove duplicate provider_health provider_id index

provider_health already has PRIMARY KEY (provider_id, app_type), so SQLite maintains an index whose left-most key is provider_id; adding idx_provider_health_provider duplicates that access path and does not speed up any additional query patterns in this codebase (all provider_health lookups by provider also include app_type). This extra index adds write amplification and database bloat on every health upsert/delete, which is the hot path for proxy traffic.

Useful? React with 👍 / 👎.

[],
)
.map_err(|e| AppError::Database(format!("创建 provider_health provider 索引失败: {e}")))?;
}

if Self::table_exists(conn, "providers")?
&& Self::has_column(conn, "providers", "sort_index")?
{
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_providers_app_sort ON providers(app_type, sort_index)",
[],
)
.map_err(|e| AppError::Database(format!("创建 providers app_sort 索引失败: {e}")))?;
}

log::info!("v6 -> v7 迁移完成:已添加性能索引");
Ok(())
}

/// 插入默认模型定价数据
/// 格式: (model_id, display_name, input, output, cache_read, cache_creation)
/// 注意: model_id 使用短横线格式(如 claude-haiku-4-5),与 API 返回的模型名称标准化后一致
Expand Down
Loading