从大表中选择行并更新它们的问题

时间:2017-03-30 23:51:05

标签: php mysql performance

我总共有7张桌子。其中1个将用作与其他6个的比较,它将从另一个更新列5.就列数而言,这些列不多,主表总共有17列。但行,主表有大约66,000行。现在我一直在进行一些研究,并将表格设置为MYISAM而不是InnoDB,但是在负载速度方面没有看到太多变化。所以这是我最初的方法:

  1. 从表1中选择所有行然后在PHP中执行foreach行获取某些列值并对其他6个表中的每一个执行特定选择以返回单个值:

    $all = $table1->selectAll();
    foreach( $all as $a_template ){
          $id = $a_template['id'];
    
          $table2 = new Table2();
          $table3 = new Table3();
          $table4 = new Table4();
          $table5 = new Table5();
          $table6 = new Table6();
    
          $table2->select($a_template['column1']);
          $table3->select($a_template['column2']);
          $table4->select($a_template['column3']);
          $table5->select($a_template['column4']);
          $table6->selectByCode($a_template['npsecondarycode']);
    
          $table1 = new Table1();
          $table1->update($table2->getColumnVal(), $table3->getColumnVal(), $table4->getColumnVal(), $table5->getColumnVal(), $table6->getColumnVal(), $id);
    
        }
    
  2. 被调用的函数" getColumnVal()"它所做的只是返回执行select时设置的值,而不是那里的biggie。

    现在这个过程需要大约15到20分钟才能完成66,000条记录,而且我还没有能够加速它,在某些情况下导致内存问题,我必须升级内存限制为至少1GB。

    我确实尝试直接通过MySQL并使用内部联接进行选择,因为我听说数据库可以使用更大的数据和更好的速度进行更强烈的查询,但在这种情况下它实际上会锁定并停止所有工作在某些情况下,PhpMyAdmin给我一个500错误。

    我不知道从哪里开始,因为我之前从未遇到过这种情况。如果有人能指出我应该采取哪些措施来提高处理这些数据的性能和速度,我将不胜感激。 TY:)

    更新:这里是基于Rick James'的实际查询。回答:

    UPDATE templates AS t
             JOIN equipos as e ON e.codigos  = t.npsegment1
             JOIN ubicaciones u ON u.attribute1  = t.atributo1
             JOIN tiendas ti ON ti.nombre_doc_stock = t.atributo1
             JOIN estados es on es.nporganizationid  = t.nporganizationid
             JOIN almacenes a on a.npsecondarycode  = t.npsecondarycode
             SET t.inclusion = e.inclusion,
                 t.ubicacion = u.ubicacion11,
                 t.tienda_id = ti.idi2b,
                 t.estado = es.estado,
                 t.considerar = a.considerar
    

    表格模板有66K记录

1 个答案:

答案 0 :(得分:2)

查找多表UPDATE。您可以在单个SQL语句中执行整个操作。它运行得更快。像

这样的东西
UPDATE table1
    JOIN table2 ON ...
    JOIN table3 ON ...
    ....
    SET table1.col1 = ...,
        table1.col2 = ...,
        ....;

不要使用MyISAM。

更多

查询是将多个表中的内容复制到一个表(t)中?如果您从头开始创建t,那么INSERT INTO t SELECT ... JOIN ...

可能要快得多

如果您确实需要大量更新,如果列是独立的,那么一次执行一个表可能会更快。也就是说,

UPDATE t JOIN e ON ... SET t.inclusion = e.inclusion;
UPDATE t JOIN u ON ... SET t.... = u....;
etc.

我怀疑部分问题是在如此多的表中锁定了这么多行。

另一种方法是" chunk"完成任务。我讨论here。它总体上需要更长的时间,但每个块都将在文明的时间内完成。