V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
hujianxin
V2EX  ›  程序员

数据库查询太慢,无法优化。。。

  •  
  •   hujianxin · 2017-07-28 17:36:21 +08:00 · 4456 次点击
    这是一个创建于 2701 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大佬们好,我现在遇到一个问题,希望大佬可以帮忙解答一下。

    我需要在一个数据库里读取数据,现在这个数据库的现状是:

    1. 这个数据库是别人的数据库,我只负责读,而且只能在这里读,而且不能修改这个数据库。
    2. 数据库里面表结构比较复杂,数据量大,每次查询需要的数据都需要很长时间。10 万条数据需要 5 分钟吧。
    3. 如果我在前端页面提供了某些条件,让用户提交确定,然后后台去查询,再计算,那样用户就需要在电脑屏幕前等待好久,用户体验很屎,几乎没法用。

    我的问题描述的差不多了。

    我现在的想法是,通过一个后台线程,定时的去查询数据库,然后将 join 之后的数据,插入到我的数据库中。然后我的 web 引用只需要查询我的数据库,就免去了 join 的操作。速度会有大的提高。至于缺点呢,我能想到的就是,因为需要定时计算,所以最新的几个小时的数据,我没法提供查询。

    各位大佬,面对这样的问题,您有什么解决方案吗?

    您觉着我的这个方案可行吗?

    谢谢啦!

    27 条回复    2017-07-31 10:53:22 +08:00
    234747005
        1
    234747005  
       2017-07-28 17:42:37 +08:00
    首先你要说一下你在用的是什么数据库。。
    noNOno
        2
    noNOno  
       2017-07-28 17:42:53 +08:00
    做个缓存,当然可以了。
    hujianxin
        3
    hujianxin  
    OP
       2017-07-28 17:44:19 +08:00
    @234747005 用的是一个 Oracle,里面放了有 2t 的数据,暂时。速度很慢。
    @noNOno 缓存的方案我想一下,估计可能占用内存太大了,谢啦
    hujianxin
        4
    hujianxin  
    OP
       2017-07-28 17:45:07 +08:00
    @234747005 他们的数据库,我也没法优化,人家只是让我们查询
    suixn
        5
    suixn  
       2017-07-28 17:49:47 +08:00   ❤️ 1
    https://github.com/alibaba/yugong
    用这个先全量同步一份数据,之后实时同步对方数据过来。
    这样就可以只用你的库了。
    hujianxin
        6
    hujianxin  
    OP
       2017-07-28 17:53:29 +08:00   ❤️ 1
    @suixn 只用我的库也是不行的,我的问题不是数据传输慢,而是 join 什么的速度慢,用我自己的数据库也是很慢很慢,
    suixn
        7
    suixn  
       2017-07-28 17:56:08 +08:00
    @hujianxin #6 同步过来做优化嘛,分库分表,加索引什么的。当然,先看看 sql 本身有没有可以优化的地方。
    asen477
        8
    asen477  
       2017-07-28 17:56:36 +08:00
    做数据缓存,能解决部分问题。
    syncher
        9
    syncher  
       2017-07-28 17:59:10 +08:00
    看到 #3 中的 Oracle, 吓得我撒腿就跑!
    assad
        10
    assad  
       2017-07-28 18:04:08 +08:00
    忍吧,别人的库,你没法搞这个那个的,唯一能优化的,就是结果缓存。
    什么分表,索引,你有权限改么,没的话就没什么办法了
    hujianxin
        11
    hujianxin  
    OP
       2017-07-28 18:04:57 +08:00
    @suixn 是个解决办法,哈哈,谢啦
    hujianxin
        12
    hujianxin  
    OP
       2017-07-28 18:05:37 +08:00
    @assad 我说的这种,使用后台线程整理数据库结果的方式,您觉着可行不?
    LosLord
        13
    LosLord  
       2017-07-28 18:05:45 +08:00 via Android
    select * form table 全查过来
    fds
        14
    fds  
       2017-07-28 18:05:52 +08:00
    用户查询后就立即把这次查询出来,但注明查询中。等一会儿有结果了,通知用户查看结果。结果永久保存在本地,可以随时查看。既然查询速度不能提高,只能是让用户忍忍咯。或者你缓存下结果,如果有一个用户查过了,其他人可以直接看。
    sampeng
        15
    sampeng  
       2017-07-28 18:24:41 +08:00
    你这相当于数据缓存了。。当然可行。问题就在于重新 flush 你自己的数据缓存的时间。新数据会得不到。
    如果对方系统你可以干预,让他在 insert 的时候通知一下你去更新你数据库
    hujianxin
        16
    hujianxin  
    OP
       2017-07-28 18:26:18 +08:00
    @fds 可以通过邮件通知,是个好方法,谢谢啦!能在一定程度上解决这个设计很渣的现状。缓存在本地的话,估计会占用大量的内存,缓存过期,还是很渣,我自我感觉,缓存在我这个问题上,发挥的作用可能不太大。
    hujianxin
        17
    hujianxin  
    OP
       2017-07-28 18:29:02 +08:00
    @sampeng 谢谢提出建议。我的这种情况,不算缓存吧,我是把整理后的结果放到我自己的 mysql 里面了,然后加上索引,避免了 join,所以速度会快。您说的 flush 数据缓存,我不太明白呢,希望您能说的具体一下,谢谢了。对方的数据库,不让动呀,我打算一个小时增量查询一次。然后继续插入我的数据库。
    我这样描述的话,您觉着合适吗?
    misaka19000
        18
    misaka19000  
       2017-07-28 18:36:01 +08:00 via Android
    增加定时抓取的频率,尽可能保证数据完整
    danielmiao
        19
    danielmiao  
       2017-07-28 18:37:16 +08:00
    扔到 es 做检索
    stabc
        20
    stabc  
       2017-07-28 18:39:38 +08:00
    我读到一半首先想到的就是你自己的这个方案,就是读到自己的数据库里。
    最新数据的更新方案,不了解你的具体业务流程也没法给意见,唯一的意见就是按照这个思路走下去吧。
    wangchen
        21
    wangchen  
       2017-07-28 18:57:16 +08:00
    @hujianxin 你的方案是正确的,问题在于同步的频率和方法。

    这里面有四个部分,数据源、数据同步工具、数据转换工具、目标数据库。

    - 数据源,指那个只读库。
    - 目标数据库,指你自己设计的数据库,它可以与数据源采用不同的结构,面向查询优化。
    - 数据同步工具,不要去同步复杂查询的结果,要按主键同步每一个需要的表,速度快、可增量。
    - 数据转换工具,把增量数据转换成目的数据库要求的形式。
    ihaveobj
        22
    ihaveobj  
       2017-07-28 19:09:32 +08:00
    放你自己数据库后,如果别人更新了怎么办?如果只是增量那倒是可以

    用其他人的数据很被动,感觉还是加一层缓存,内存怕太大可以用文件缓存,优化一下应该能用
    SlipStupig
        23
    SlipStupig  
       2017-07-28 19:15:20 +08:00
    分片 缓存 读写分离
    hujianxin
        24
    hujianxin  
    OP
       2017-07-28 19:42:10 +08:00
    @misaka19000 好的,谢谢您的建议!
    @danielmiao es 我倒是用过,但是没深入的研究,你的建议非常好,我回去研究一下。
    @stabc 好的,谢谢!
    @wangchen 非常感谢,原来还有套路啊,却是,同步频率这个我可以比较轻松的优化,同步工具的话,我需要回去查一下,有什么好的工具不,谢啦!
    @ihaveobj 别人更新表结构的话,我可以更新我的导入程序,但是我这边的表结构就不变化啦。文件缓存这个,我回去研究一下,感谢!
    ncisoft
        25
    ncisoft  
       2017-07-28 20:14:13 +08:00 via Android
    改业务需求吧,oltp 不是给你干 olap 业务的:10 万条数据需要 5 分钟吧。oltp 没有这种查大数据集的用法,btree 不适合干这个
    six880214
        26
    six880214  
       2017-07-29 00:46:59 +08:00
    先看表结构,主键,外键和索引。然后尽可能的优化 sql,然后再想别的方法。
    sampeng
        27
    sampeng  
       2017-07-31 10:53:22 +08:00
    @hujianxin
    你这其实就是缓存,只是缓存的地方是数据库而已。不是只有缓存到内存才叫缓存。

    因为目标库是只读的,你也没办法要求对方给你修改的通知。那只能定时去查了。但如果修改和删除记录。你这边是不可感知的。会比较麻烦,要么全部数据对比一下然后更新。要么就是定时把整个库删掉在重建。没什么别的好办法。当然,如果只是增加。那就定时查吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1020 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 21:59 · PVG 05:59 · LAX 13:59 · JFK 16:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.