相同 Python 代碼、相同數據庫文件、相同 SQL(5 表 LEFT JOIN),Linux 秒出,Windows 10+ 秒。
| # | 原因 | 驗證方法 | 解決方案 |
|---|---|---|---|
| 1 | **缺少索引** | `.schema` 看建表語句;`EXPLAIN QUERY PLAN` 看是否全表掃描 | 為 JOIN 條件列 (`courseId`, `courseItemId`, `studentId` 等) 創建索引 |
| 2 | **SQLite 版本差異** | `sqlite3 --version` 對比;Linux 往往更新 | Windows 升級到 3.40+ (WAL 模式、查詢優化器改進) |
| 3 | **文件系統/鎖開銷** | 數據庫在 HDD/網絡盤/防毒軟件掃描目錄 | 移至 SSD 本地盤;排除防毒掃描;啟用 WAL `PRAGMA journal_mode=WAL;` |
| 4 | **Python 環境差異** | Linux 系統自帶 Python (C 編譯優化) vs Windows pip 安裝版 | Windows 用官方安裝包或 conda;嘗試 `pypy3` 運行 |
| 5 | **頁面緩存/內存壓力** | Windows 可用內存低,頁面換入頻繁 | 增加內存;`PRAGMA cache_size=-32768` (32MB 緩存) |
| 6 | **臨時文件目錄權限/速度** | Windows `TEMP` 在慢盤或無寫權限 | 設置 `PRAGMA temp_store=MEMORY;` 或指定快盤 `PRAGMA temp_store_directory='D:/tmp';` |
import sqlite3
cx = sqlite3.connect("db.s3db")
cu = cx.cursor()
# 1. 關鍵 PRAGMA (連接後立即執行)
cu.execute("PRAGMA journal_mode=WAL;") # 寫不阻塞讀,大幅提升並發
cu.execute("PRAGMA synchronous=NORMAL;") # 安全與速度平衡
cu.execute("PRAGMA cache_size=-32768;") # 32MB 頁面緩存
cu.execute("PRAGMA temp_store=MEMORY;") # 臨時表/排序在內存
cu.execute("PRAGMA mmap_size=268435456;") # 256MB mmap (需 OS 支持)
# 2. 創建缺失索引 (僅需執行一次)
index_sql = [
"CREATE INDEX IF NOT EXISTS idx_courseItem_courseId ON courseItem(courseId);",
"CREATE INDEX IF NOT EXISTS idx_courseChoose_courseItemId ON courseChoose(courseItemId);",
"CREATE INDEX IF NOT EXISTS idx_courseChoose_studentId ON courseChoose(studentId);",
"CREATE INDEX IF NOT EXISTS idx_student_id ON student(id);",
"CREATE INDEX IF NOT EXISTS idx_courseYear_id ON courseYear(id);"
]
for sql in index_sql: cu.execute(sql)
# 3. 執行查詢
sqlStr = """ ..."""
cu.execute(sqlStr)
rows = cu.fetchall()
print(len(rows))
原最佳回答「系統問題」過於籠統。上文提供 6 維具體排查表、可直接複製的 PRAGMA+索引優化代碼、底層原因分析。