V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
yeqiu
V2EX  ›  MySQL

sql 语句的优化问题

  •  
  •   yeqiu · 2015-01-08 15:36:40 +08:00 · 3316 次点击
    这是一个创建于 3616 天前的主题,其中的信息可能已经有所发展或是发生改变。
    大约23W条数据
    每条数据产生至少
    3条delete,1条update
    还有可能产生更多的
    现在情况是执行完一条数据生成的语句需要1S左右
    算下来我需要6个小时才能执行完。

    单步执行结果是发现存在一个delete语句中包含了in语句需要1s,

    DELETE
    FROM
    g_re_enterprises_types
    WHERE
    enterprise_id IN (
    SELECT
    id
    FROM
    g_enterprises
    WHERE
    enterprise_name = '广东百合医疗科技股份有限公司'
    );





    但是同样的另外一个delete语句中也包含了in语句却只要0.4s
    DELETE
    FROM
    g_enterprises_certificate
    WHERE
    enterprises_id IN (
    SELECT
    id
    FROM
    g_enterprises
    WHERE
    enterprise_name = '广东百合医疗科技股份有限公司'
    );



    有没有什么解决的思路?
    mysql Ver 15.1 Distrib 10.0.15-MariaDB, for Linux (x86_64) using readline 5.1
    14 条回复    2015-01-09 09:54:37 +08:00
    xiaogui
        1
    xiaogui  
       2015-01-08 15:51:36 +08:00
    查看 g_re_enterprises_types 表和 g_enterprises_certificate 表数据量,以及表中 enterprise_id 字段是否有索引?
    yeqiu
        2
    yeqiu  
    OP
       2015-01-08 16:08:03 +08:00
    @xiaogui
    索引和外键都是有的,数据量也都差不多
    xiaogui
        3
    xiaogui  
       2015-01-08 16:11:22 +08:00
    @yeqiu 视图呢?
    yeqiu
        4
    yeqiu  
    OP
       2015-01-08 16:12:12 +08:00
    @xiaogui 视图?什么意思?
    msg7086
        5
    msg7086  
       2015-01-08 16:14:56 +08:00 via iPhone
    不贴个EXPLAIN?
    iamshaynez
        6
    iamshaynez  
       2015-01-08 16:32:29 +08:00
    查看执行计划吧,认为执行计划已经比较高效,那么瓶颈基本上就在硬件上了。23w * 4+ 次执行的速度不是单靠优化SQL能解决的。

    求教MSSQL用exists替换in能改善性能吗?Oracle是明显改善的,尤其是10以前的版本。
    huwsun
        7
    huwsun  
       2015-01-08 16:44:58 +08:00
    考虑批量执行
    omegaga
        8
    omegaga  
       2015-01-08 17:02:48 +08:00
    @iamshaynez exists和in的性能比较要看比较吧。如果你指的是
    SELECT * FROM A
    WHERE EXISTS (
    SELECT * FROM B
    WHERE A.id = B.id
    )

    SELECT * FROM A
    WHERE A.id IN (
    SELECT id FROM B
    )
    的话,通常来说是没有明显的区别的(execution plan是一样的)。
    不过老的版本里IN会被翻译成一串OR。。。。。。那个性能就不能直视了
    yeqiu
        9
    yeqiu  
    OP
       2015-01-08 17:40:28 +08:00
    @msg7086
    两个语句的explan是一样的
    branchzero
        10
    branchzero  
       2015-01-08 17:46:24 +08:00
    可以考虑先把所有ID查出来汇总到一块儿去重,然后一次性喂DELETE?
    yuankui
        11
    yuankui  
       2015-01-08 20:25:45 +08:00
    1. 那里来的update?
    2. 这种语句在什么场景下执行?每个请求一次?每天一次?如果每天一次,几秒都是可以接受了,在怎么优化有没有多大收效
    3. 有些东西不是单单通过优化sql可以解决的,换个思路。比如把数据全部dump出来,然后分析,然后再喂回去。某些场景下效率会高很多。
    mkeith
        12
    mkeith  
       2015-01-08 20:26:24 +08:00
    2个表的数据量不一样吧?
    jc4myself
        13
    jc4myself  
       2015-01-09 00:39:59 +08:00 via iPad
    看一下开查询缓存没,或者执行两次同一条select
    thinkmore
        14
    thinkmore  
       2015-01-09 09:54:37 +08:00
    DELETE
    FROM
    g_re_enterprises_types
    WHERE
    enterprise_id exists (
    SELECT
    id
    FROM
    g_enterprises
    WHERE
    enterprise_name = '广东百合医疗科技股份有限公司'
    );

    我们几百万上千万数据都很快出来,你的为什么会这么慢呢?你explain试一试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4160 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:12 · PVG 12:12 · LAX 20:12 · JFK 23:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.