php在循环中使用 SHOW TABLES LIKE 'table'; 为什么会出现 2006, MySQL server has gone away?-灵析社区

九久九

框架:thinkphp 场景:在脚本中循环查询数据并处理,查询数据使用的model中含有分表逻辑,若分表不存在则自动创建分表。 model代码: class TestTableModel { public function getTable($date) { $r = Db::query('show tables like "test_table_{$date}"'); if (empty($r)) { // 若表不存在,则创建 Db::execute('创建 test_table_{$date} 表'); } // 使用Db对象 return Db::table('test_table_{$date}'); } } 脚本代码: $date = '20230506'; $page = 1; // 分页页码 while (1) { $db = (new TestTableModel)->getTable($date)->page($page)->select(); ++$page; // 进行一些处理 (......省略) } 这个循环只要一执行就瞬间报出 2006, MySQL server has gone away 的错误。最一开始我以为是和mysql的连接超时导致的,但后来将model中的 show tables like 这句去掉之后,代码就能正常运行了,而且运行很长很长时间也不会报错。 调整后能正确运行的model: class TestTableModel { public function getTable($date) { // 使用Db对象 return Db::table('test_table_{$date}'); } } 所以现在的问题就是,为什么加上 show tables like 这句查询就会导致 2006, MySQL server has gone away ? 然而如果这个model不在循环中使用也不会报错,而且在mysql中执行show tables like速度也很快,有点搞不懂。当前查询中的分表是存在的,而且数据库的数据表总量也就近百个。原因在哪里呢?

阅读量:15

点赞量:0

问AI
可能的原因会很多,可以参考 "MySQL 手册" (https://link.segmentfault.com/?enc=uV%2BzI%2BcPIr1LhA1i82R1fA%3D%3D.0iji%2Fxwk1UrnuI5whnKKq0%2BWpAA5f2XLIp99On85oWw0NHcCv0x4dBXUEsGsqBVYllKnAqQn7H3QhglE4Bqq%2F5WxQMu%2F%2BmVimcucawHVkx%2FdWaUK4Wnyf082nP1zLdjbpHgiAdNJO7pRnZ%2BLN%2BXviujwif2%2F6v4kCYF1AcQqrNEuqCxvVrtoWJVbZ1YGAWf%2FJvCDD3ijFaoii0Njgd6E%2Bw91Pz7yWnYsSgIyRwOF161HRe5f6QV4WIH1kJvmW7LA6EtZf47Y1Ma0kP6%2Bl5RtaRPkNVN3%2FHJi1%2BzixC6JKcs92pa4D0X%2BK8d7o9RvJG%2BQVL7B0bEEa5YQscknasnA7m5iZcGVrwuooX%2BYgU7C6ohWep3Oge5mqqSNV8zl5%2BNJflIuE8hsQjdTAkoogABHJkH%2F4U5q6b56wArZRhHH6wFQ9QLOzyz5j2APiWMRGRNrK4Tz1ZVn5siWYvlXgWIl9tjctZhD9WpmxPlr5v9%2Bhk18OyFELULlpjHJ6M30Wk5gshII0%2BJ1eMVe747qAU7nCQ%3D%3D) 中的说明去解决。 如果你只想简单解决问题,那有更简单的方法,就是自动重连,参考 ThinkPHP 手册中关于 "断线重连" (https://link.segmentfault.com/?enc=WwbxV4J4xyiK%2F3x1F%2FqL%2Fw%3D%3D.z%2FiE06GpT0wfnDUn0noZoFJJbT1%2FqDeIXMX813ds7%2FGE6Xek2oU8cZlC%2F%2BILXwWn) 的配置介绍。 *** 另外,你这种方式会存在一些意外风险,在 MySQL 中,DDL 语句是会自动提交事务的,如果你的代码在事务中运行,且这个表不存在的时候,走到了创建表的语句,就有可能导致事务被意外的提交了,基于这个原因,你得建表操作最好在外部完成。 除此之外,在一些情况下,你还可以有其他的优化方案来查询你这个 show tables,你可以在循环外面使用:"show tables like 'test_table_%'",将指定前缀的表取出来,存为变量,然后用 php 去判断就好了,而不是现在这样每次都查询。如果循环比较多,可能在这个期间创建了表,那你还可以考虑每 N 个或者每 N 秒后,执行一下上面的语句,重新覆盖一下。