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

mysql online DDL 时间很长,咋整,数据量不多,就 30W

  •  
  •   hhhhhh123 · Jan 8, 2025 · 3980 views
    This topic created in 627 days ago, the information mentioned may be changed or developed.

    下面是说明和当时场景
    mysql 版本 8.0+
    当初设计的时候还是欠考虑了。 唉~
    sql 中的 date() 函数用的时候一时爽, 现在头大。

    我自己的 app 基本上所有的时间查询我都使用了 date 函数 QAQ
    现在哭着改代码 QAQ ~
    比如

    select uid, balance, create_time from day_check_in where date(create_time) = date(%(入参时间)s) and uid = '123';
    

    近期想优化接口,使用 EXPLAIN 一看头皮发麻, 虽然目前数据量不多,但是很难看。

    当我翻看文档和搜索后发现 可以使用 online DDL 创建索引的时候 可以尽可能的不影响 CURD 操作,不过一些 特殊的 sql 还是会影响,会等待创建索引后才能执行一些查询。 不过这个问题不大,因为我可以避开这个时间段!

    后面我执行了

    ALTER TABLE balance_records ADD INDEX index_uid_create_time (uid, create_time)
    

    发现执行了 5 分钟还是没有执行成功。 使用 SHOW PROCESSLIST; 查看 sql 的运行情况,发现没有什么 sql 和创建索引 sql 冲突, 意味着 创建索引 sql 还在执行。

    我以为是数据量大的原因, 当我把这个表所有的数据拷贝到 test 库中, 我执行了 创建索引的指令,结果 2 秒就执行完了。
    我想知道为啥?
    目前一直没有找到问题所在, 我已经尝试了两个表,拷贝的表单都是几秒钟就创建完成了! 唯独开发环境的表没有执行成功。
    目前唯一能想到的办法就是在夜深人静的时候,进行停止服务,再执行创建索引操作,也不知道行不行。

    有没有大佬知道 为啥我拷贝的表执行几秒钟就执行完了。

    16 replies  •  2025-01-25 11:25:35 +08:00
    bobobobob
        1
    bobobobob  
       Jan 8, 2025
    有在线 DDL 的库的,允许数据库一边提供服务,一边在线 ddl

    或者在后半夜开启只读模式
    rekulas
        2
    rekulas  
       Jan 8, 2025
    没冲突,但是要看看 ddl 的状态呢,有没可能是因为在等待中, 比如这种情况有程序事务未释放,你在进程可能看不到执行语句但后面的语句就是阻塞了
    june4
        3
    june4  
       Jan 8, 2025
    为何要多此一举二边加 date 函数呢?还会导致索引不能用了。
    seers
        4
    seers  
       Jan 8, 2025 via Android
    肯定有锁了,看看是不是在 lock wait
    yc8332
        5
    yc8332  
       Jan 9, 2025
    搞不懂为啥要用 date 函数。。。。正常不都记录时间戳吗
    spritecn
        6
    spritecn  
       Jan 9, 2025
    @yc8332 列表选时间,不都是按天的?
    chengquan17
        7
    chengquan17  
       Jan 9, 2025
    30w 能算大表了?整表也就几十 MB ,建索引正常都是秒级吧
    RangerWolf
        8
    RangerWolf  
       Jan 9, 2025
    如果 create_time 的数据不是非常集中的情况下 :

    1. create_time 加索引
    2. 改 SQL , 不能使用 date(create_time)的方式,索引会失效, 改成 create_time between 的方式

    30W 的数据 应该不多,加了索引应该生效挺快的

    类似的 uid 也可以尝试加索引
    hhhhhh123
        9
    hhhhhh123  
    OP
       Jan 9, 2025
    @RangerWolf #8 所以我最近在改代码,理论上这数据确实不多,加索引应该很快,但是确实执行了很久都没有成功!
    hhhhhh123
        10
    hhhhhh123  
    OP
       Jan 9, 2025
    我知道 date 索引会失效 呀
    asmile1993
        11
    asmile1993  
       Jan 9, 2025
    1 、8.0 有函数索引了
    yc8332
        12
    yc8332  
       Jan 9, 2025
    @spritecn 直接用时间戳就能解决了啊。。
    spritecn
        13
    spritecn  
       Jan 10, 2025
    @yc8332 date(create_time) = date(%(入参时间)s) ,op 只是不配写 betwwen and 而已,结果坑有点多
    hhhhhh123
        14
    hhhhhh123  
    OP
       Jan 11, 2025
    @spritecn #13 一语中的, 确实是这样, 写代码的时候 偷懒用的 date ,现在改代码填坑。数据库为什么不用时间戳, 因为 年月日时分秒 好看而已, 自己查询的时候 也方便一点而已。
    wenxueywx
        15
    wenxueywx  
       Jan 24, 2025
    猜测有长事务占据元数据锁没有释放
    nakar
        16
    nakar  
       Jan 25, 2025
    @hhhhhh123 KPI 填上,优化提高了性能,doge
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1267 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 16:50 · PVG 00:50 · LAX 09:50 · JFK 12:50
    ♥ Do have faith in what you're doing.