Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:连接3个表的更新查询运行时间很长(15M行表,索引)_Mysql_Sql_Sql Update - Fatal编程技术网

MySQL:连接3个表的更新查询运行时间很长(15M行表,索引)

MySQL:连接3个表的更新查询运行时间很长(15M行表,索引),mysql,sql,sql-update,Mysql,Sql,Sql Update,我在3个表中有15万行(一个表是原始CSV导入,另外两个是该CSV的标准化版本+一些其他数据) 我只需要从原始CSV表中更新一个字段。连接这些表的更新查询现在已经在我的四核8GB-ssd机箱上运行了30个小时 这正常吗?有没有更好的方法来执行这个简单的更新 首先,如果非规范化数据有1300万条记录,但两个“规范化”表都有1700万条记录,那么规范化不会带来太多压缩 其次,您试图在一条SQL语句中更新两个规范化表。我认为应该首先更新映射表,然后在第二条SQL语句中更新数据表 第三,执行内部联

我在3个表中有15万行(一个表是原始CSV导入,另外两个是该CSV的标准化版本+一些其他数据)

我只需要从原始CSV表中更新一个字段。连接这些表的更新查询现在已经在我的四核8GB-ssd机箱上运行了30个小时

  • 这正常吗?有没有更好的方法来执行这个简单的更新


首先,如果非规范化数据有1300万条记录,但两个“规范化”表都有1700万条记录,那么规范化不会带来太多压缩

其次,您试图在一条SQL语句中更新两个规范化表。我认为应该首先更新映射表,然后在第二条SQL语句中更新数据表

第三,执行内部联接可以加快速度,因为您的查询执行的是三向笛卡尔积。嗯,不完全是这样,因为您只是在执行join老派,优化器应该选择它,但无论如何,使用join语法

UPDATE item_catalog_map AS icm
       INNER JOiN temp_input AS ti
          ON icm.catalog_unique_item_id = ti.productID
  SET icm.price = ti.retailPrice,
      icm.conversion_url = productURL;


UPDATE item AS i
       INNER JOIN temp_input AS ti
          ON i.id = icm.item_id
  SET i.name = ti.productName;
最后,确保您拥有的索引是:

CREATE INDEX IDX_CATALOG ON item_catalog_map (catalog_unique_item_id);
CREATE INDEX IDX_RAW_PRODUCT_ID ON temp_input (productID);
CREATE INDEX IDX_RAW_ITEM_ID ON temp_input (item_id);

有什么帮助吗?@davidparks通常,如果您的表没有索引,您的效率会很低。使用的数据库引擎是什么?例如:InnoDB或ISAM。。。同样,如果您使用的是ISAM,那么每次您更新一个键或添加一个记录时,您都会确保表被重新索引。最后,运行SELECT和UPDATE是两件不同的事情。然而,难道你没有比这样在三者之间进行n个内部联接更好的方法吗?根据你的问题,你只需要更新
i
中的一个字段。但是,您的查询也在更新
icm
中的两个字段。你能澄清一下吗?这些表肯定是索引的,“可能的_键”表明我们使用了2个主键和一个索引列(在没有主键的映射表icm上)。引擎设置为InnoDB。这些表是一周前新创建的,并没有删除操作,所以不确定优化表。唯一值得注意的是,我可能会说,我使用的是文本字段,而不是VARCHAR,但我没有看到任何关于InnoDB的警告。icm表是一个映射,它是必需的,因为有多个数据集(比如ti1、ti2、ti3,所有不同的CSV导入)将映射到I(项目)表(多个ti到一个I行)。因此,映射对于识别ti1、ti2等和i(项)表之间的重复项是必要的。我已经尝试了您的第二个注释,只是更新映射表,所以只需在主键上加入1个连接-VARCHAR(255)键,我现在已经超过24小时了。我正在按照您的建议进行单独的更新,祈祷成功。:)关于您的第一条评论,我认为映射表对于最初创建item表是必需的,并且对于创建新记录也是必需的。但是,您所做的只是从CSV导入更新产品名称,因此我认为在第二个查询中不需要它。为了创建记录,我仍然会填充映射表而不填充item表,然后使用一条SQL语句填充item表,并将其连接到映射表。
CREATE INDEX IDX_CATALOG ON item_catalog_map (catalog_unique_item_id);
CREATE INDEX IDX_RAW_PRODUCT_ID ON temp_input (productID);
CREATE INDEX IDX_RAW_ITEM_ID ON temp_input (item_id);