我正在尝试使用另一个表中的数据更新表格,我想将缺少的纬度和经度添加到缺少该数据的“公司”表中。我有一个邮政编码表及其相应的纬度和经度,但我需要正确格式化公司邮政编码(更改为大写,并删除空格)。
理想情况下,我想将此作为一个查询,所以我写了这个:
UPDATE companies as c JOIN add_postcodes as p
ON p.postcode = UPPER(replace(c.company_postcode, ' ', ''))
SET
company_latitude = add_postcodes.Latitude,
company_longitude = add_postcodes.Longitude
WHERE company_longitude IS NULL AND company_postcode != ''
哪个有效,但是花了很长时间(几乎字面意思)
所以我随后将其更改为首先更新公司表中的邮政编码,然后运行更新。
UPDATE companies
SET postcode = UPPER( REPLACE( company_postcode, ' ', '' ) )
UPDATE companies JOIN add_postcodes
ON companies.postcode = add_postcodes.postcode
SET company_latitude = add_postcodes.Latitude,
company_longitude = add_postcodes.Longitude
WHERE company_longitude IS NULL AND company_postcode != ''
这真的很快。
现在我想我理解为什么会这样,但我想知道我是否可以重写我的单个查询也很快,这也意味着我不必改变公司表中的列。
我知道我本可以创建一个添加列,不要更新然后删除列,但这对我来说比生产就绪解决方案更像是一个学习练习。
感激地收到任何指示。
答案 0 :(得分:0)
第一个版本缓慢的原因是因为join子句p.postcode = UPPER(replace(c.company_postcode, ' ', ''))
必须对满足where子句条件的companies表中的每一行执行字符串操作。如果公司表中的邮政编码列上有索引,则不会使用该索引。
您可以通过运行多个查询来加快速度。例如,如果有大量记录不需要对连接进行字符串操作,则可以运行:
UPDATE companies as c JOIN add_postcodes as p
ON p.postcode = c.company_postcode
SET
company_latitude = add_postcodes.Latitude,
company_longitude = add_postcodes.Longitude
WHERE company_longitude IS NULL AND company_postcode != ''
在运行其他查询之前。由于此查询将设置经度列,因此受影响的记录将与where子句不匹配,并且应在连接发生之前过滤掉。
您可以尝试的另一件事是省略UPPER函数 - 在比较字符串时,MySQL默认为not case sensitive。这可能会更快:
UPDATE companies as c JOIN add_postcodes as p
ON p.postcode = replace(c.company_postcode, ' ', '')
SET
company_latitude = add_postcodes.Latitude,
company_longitude = add_postcodes.Longitude
WHERE company_longitude IS NULL
AND company_postcode != ''