V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
heliumjt
V2EX  ›  程序员

新手请教一下,我的数据库系统有多少改进的空间?

  •  1
     
  •   heliumjt · 335 天前 · 1676 次点击
    这是一个创建于 335 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我自己是纯业余爱好者,没上过一点科班课程,这段时间靠 GPT 全程答疑搭了一个卡牌查询网站 https://sbwsz.com/ ,数据量大概在 10w 条左右,后端用的是 SQLAlchemy+SQLite 。目前感觉查询性能很一般,很多查询要接近 1 秒的时间才能出结果,光查询用时就是其他卡查网站整个网络请求用时的好几倍。
    我首先想到的肯定是查询语句的优化不够。但是由于卡查很多地方是文本模糊匹配,SQLite 这方面的性能好像不太行,我感觉优化的空间不太大。问了问 GPT ,它建议我改用 PostgreSQL 或者 Elasticsearch 。或者,由于数据量比较小( 10w 条数据大概 1GB 左右),是不是可以直接放内存里用 redis 之类的内存数据库管理?
    13 条回复    2023-12-11 17:39:12 +08:00
    gxy2825
        1
    gxy2825  
       335 天前   ❤️ 1
    这种文本模糊搜索很适合用 Elasticsearch ,但是考虑到技术难度和数据量不一定是优选,如果数据量增长的不快可以先用 Redis 试试
    AllanAG
        2
    AllanAG  
       335 天前   ❤️ 1
    文本模糊搜索的话,redis 可能不是好选择。es 可以但没必要,可以使用些轻量级的搜索引擎,比如 Meilisearch
    zzl22100048
        3
    zzl22100048  
       335 天前   ❤️ 1
    可以试试 slqite 的分词器,做模糊搜索,上 redis 感觉还不如正规的搜索引擎呢 像 https://github.com/valeriansaliou/sonic 这种
    lmq2582609
        4
    lmq2582609  
       335 天前   ❤️ 1
    这个网站是用什么搭建的呀,很不错啊!有现成的开源项目吗?
    10W 数据如果后续新增的数据量非常小,感觉上 Elasticsearch 太重了,增加维护成本。
    你可以在阿里云或者腾讯云平台申请免费试用 1 个月的 PostgreSQL 或 MongoDB 数据库,然后把数据写进去,试试看哪个能满足你的需求。
    rekulas
        5
    rekulas  
       335 天前   ❤️ 1
    可以考虑放 sphinx,这点数据量挺轻松
    或者找一个其他开源搜索框架自己做 不过要说到效果上一般的框架可能还是比不过 es(框架很多 但权重得分计算做得好的不多)
    heliumjt
        6
    heliumjt  
    OP
       335 天前
    @lmq2582609 前端就是 Vue+Element ,没有别的框架了。对比了一下之后我决定先上 PostgreSQL 试一下,因为我项目里也不只是文本查询,还有很多复杂的条件查询,我自己还是得 SQL 才玩得明白。
    suuuch
        7
    suuuch  
       335 天前
    SQLite 的话,换 SSD ,会有一点提升。

    文本检索上 ES 是标准方案,但是光是 ES 集群就够整的了。

    用 PostgreSQL 然后设计一下数据结构,和索引,应该是可以的。。(不知道数据长什么样,不做任何保证
    isSamle
        8
    isSamle  
       335 天前
    为什么不用 mysql
    maichael
        9
    maichael  
       334 天前
    ES 太重的话,可以用 meilisearch 替代。
    aru
        10
    aru  
       334 天前
    ES 用 docker 来搭建一个单节点的也还好
    不过你的硬件是什么呢?单节点的 ES 配合你的网站,建议也要 4G 内存的机器
    kuanat
        11
    kuanat  
       334 天前   ❤️ 1
    我大概试了一下网站,没感觉查询有什么特别慢的地方。如果要定位慢查询的问题,最好贴上语句和配置信息什么的看一下。

    在不改变技术框架的情况下,优化方案就是加索引。再具体一点,这个索引是要能通过用户输入的关键词,快速定位到特定字段包含关键词的数据集。

    这里涉及到两个主要的技术点,一个是对文本字段进行分词,提取出关键词。另一个是通过关键词反查数据集,这个要构建的索引叫倒排索引( inverted index )。剩下的事情就是更改查询逻辑,前端查询请求走索引,后端直接取索引筛选出的数据集。(这个索引可以做到后端应用程序里,也可以保存到数据库里)

    考虑到楼主非专业开发,我是建议手动做上面的事情。用其他的成熟方案,需要学习的东西其实更多,原理理解不到位的话很可能达不到效果,而且没有必要。


    如果是我来做这个事情的话,可能会采取完全不同的方案,楼主可以参考一下。

    因为这个数据库基本上是只读不写的,写场景基本只发生在数据修正或者批量更新的时候。所以优化的核心思路就是数据集(数据库)为查询优化。

    虽然楼主没有透露这个数据库的表结构,考虑到万智牌大概就几万张,而数据集大概有 10 万条,这个数据库应该是冗余很低,符合范式的设计方式。

    这一类数据库是为写操作和存储优化的,冗余很低,提取数据需要对数据表做组合查询。为读操作和查询优化的数据库正好相反,冗余很高。既然最终查询结果是卡牌集合,那就以某种数据结构来记录每张卡牌包含的所有信息,一次读取即可获得完整数据,省去了数据组合的过程。

    即便有大量的冗余,内存中以这种数据结构存储卡牌信息,可能不会超过 4GB ,即使再翻个倍也不是问题。那对于查询系统来说,有没有 sql 数据库都不重要了。

    当然 sql 对于数据录入还是很有意义的,一方面可能本身数据来源导入比较方便,另一方面修改低冗余数据远比高冗余数据方便。所以这里需要编写个脚本,在每次 sql 数据库更新之后,重新生成一份通用格式的(比如 csv 或者 json )的数据集,后端应用程序反序列化之后即可获得上述的内存数据库。

    上面这些如果用技术语言描述,就是 sql 转 kv/nosql ,没有多少技术难度,就是个经验问题。

    剩下的事情都差不多,分词、建索引。主要是一些经验层面的优化,这里就随便列举几个。

    比如请求是可以缓存的,一般用在高频查询和分页上。再比如具体到这个查询场景说,一个请求如果需要返回几百个数据,要么不合理要么没必要。(人一般不需要这么多,返回太多都是在给爬虫服务了。)
    dayeye2006199
        12
    dayeye2006199  
       334 天前 via Android
    PG 的全文搜索。多大网站得上 es
    heliumjt
        13
    heliumjt  
    OP
       332 天前
    @kuanat 哇,太详细了!我好好研究一下您的回答。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5340 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 08:33 · PVG 16:33 · LAX 00:33 · JFK 03:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.