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
gpra8764
V2EX  ›  MySQL

SQL 小白咨询个性能优化方案

  •  
  •   gpra8764 · 2021-02-24 17:45:24 +08:00 · 2250 次点击
    这是一个创建于 1150 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简单描述就是我有很多条数据,比如:

    a = 1, b = 0, c = 1, d = 0

    然后我有一堆新数据:

    a = 0, b = 1, c = 1, d = 0

    我想要把他们合并起来取相对大一些的值,最后得到:

    a = 1, b = 1, c = 1, d = 0

    现在有 1w 条数据我挨个用子查询判断是 REPLACE 还是 IGNORE,太慢了,精神崩溃

    想问问大佬们这种需求一般都是怎么优化处理的

    caola
        1
    caola  
       2021-02-24 17:49:34 +08:00
    a b c d 分成多个字段来存
    kiracyan
        2
    kiracyan  
       2021-02-24 17:49:50 +08:00
    a = 1, b = 0, c = 1, d = 0 是什么鬼数据 你先把表结构写清楚
    jintianfengda
        3
    jintianfengda  
       2021-02-24 17:51:55 +08:00
    意思就是有 a,b,c,d 四个字段,然后每个字段是数值类型,合并的意思是求和?还是取最大?需求还是没看太明白
    JKeita
        4
    JKeita  
       2021-02-24 17:52:23 +08:00
    意思是求每列的最大值?
    haoz1w0w
        5
    haoz1w0w  
       2021-02-24 17:53:11 +08:00
    用程序比较
    l00t
        6
    l00t  
       2021-02-24 17:53:16 +08:00
    不是很清楚你描述的场景到底是个怎么回事…… 就我的理解,你可以简单聚合一下:

    select max(a), max(b), max(c), max(d) from t
    philchang1995
        7
    philchang1995  
       2021-02-24 17:59:36 +08:00
    同上,按照现在的描述 这几个字段是分开存储的 number 的话 直接用函数就可以了
    gpra8764
        8
    gpra8764  
    OP
       2021-02-24 18:03:02 +08:00
    是有点没描述清楚,直接上 SQL 直接点:

    ```
    create table xxx (
    key tinytext,
    flag bool
    );
    ```

    现在有数据

    ```
    (key, flag) values ((a, 1), (b, 0), (c, 1), (d, 0))
    (key, flag) values ((a, 0), (b, 1), (c, 1), (d, 0))
    ```

    a,b,c,d 是 row,大概 1w 行,希望高效的合并出结果

    ```
    (key, flag) values ((a, 1), (b, 1), (c, 1), (d, 0))
    ```

    也就是 a = max(a1, a2)

    因为是 bool,每行的 flag 只会有 0 和 1 两个值
    aeli
        9
    aeli  
       2021-02-24 18:03:54 +08:00
    我理解楼主是说有 1w 条旧数据,有 1w 条新值要根据条件更新?

    这种需求 sql 做本身就会比较慢,快一点的方式,就是把旧值查出来,程序里对比一下,然后再批量 update 回去?
    aeli
        10
    aeli  
       2021-02-24 18:05:00 +08:00
    只有 0 和 1 ?那你 max 不就 1 么。。新值只有 1 的时候再去更新不就行了,不用操心旧值是啥
    @gpra8764
    gpra8764
        11
    gpra8764  
    OP
       2021-02-24 18:07:42 +08:00
    @aeli 感觉一口气全取出来用程序比再 update 回去可能的确优很多

    用 max 我还是相当于要逐行 query 一下原结果?
    aeli
        12
    aeli  
       2021-02-24 18:13:35 +08:00
    @gpra8764 max 是让 mysql 帮你做了,要生成临时表,要对涉及的行加锁。
    反正从你这 0/1 的需求来看,你根本不用比,只更新值为 1 的字段不就行了,不用管旧值是多少。
    gpra8764
        13
    gpra8764  
    OP
       2021-02-24 18:16:34 +08:00
    @aeli 主要是偶尔会出现 flag 为 0 的新行,行的 key 不是固定那 1w 个
    dktsy
        14
    dktsy  
       2021-02-24 18:21:42 +08:00
    select key, max(flag) from xxx group by key

    楼主是想实现这个吗
    gpra8764
        15
    gpra8764  
    OP
       2021-02-24 18:26:23 +08:00
    @dktsy 类似这个效果。emmm,这么一看建个临时表洗一遍,估计差不多就可以了,茅塞顿开啊。感谢大佬 :)
    aeli
        16
    aeli  
       2021-02-24 18:55:30 +08:00
    @gpra8764 那只要 insert ignore 一下新数据不就行了。update 只 update flag = 1
    jeeyong
        17
    jeeyong  
       2021-02-25 05:19:40 +08:00
    sql 只取值.
    所有 a 读出来, 做成一个 list, 排序取最大值, 就算不用任何算法, 1w 得数据量再本地速度应该可以接受..
    依次, 读取 b, 排序取值
    或者干脆都读下来, 排序取值....
    可行吗?
    gpra8764
        18
    gpra8764  
    OP
       2021-03-01 17:06:47 +08:00
    @aeli 就是因为 1w 条挨个 insert ignore 很慢,所以我才很头疼。不过已经找到方案了,先建临时表,然后把新旧值 group 后取大值就好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2981 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:21 · PVG 16:21 · LAX 01:21 · JFK 04:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.