优化Mysql查询

时间:2013-12-11 10:34:14

标签: mysql sql

我正在尝试使用另一个表中的数据更新表格,我想将缺少的纬度和经度添加到缺少该数据的“公司”表中。我有一个邮政编码表及其相应的纬度和经度,但我需要正确格式化公司邮政编码(更改为大写,并删除空格)。

理想情况下,我想将此作为一个查询,所以我写了这个:

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 !=  ''

这真的很快。

现在我想我理解为什么会这样,但我想知道我是否可以重写我的单个查询也很快,这也意味着我不必改变公司表中的列。

我知道我本可以创建一个添加列,不要更新然后删除列,但这对我来说比生产就绪解决方案更像是一个学习练习。

感激地收到任何指示。

1 个答案:

答案 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 != ''