数据库查询太慢,无法优化。。。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
hujianxin
V2EX    程序员

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

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

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

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

    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     Solana     1024 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 18:37 PVG 02:37 LAX 11:37 JFK 14:37
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86