在MySQL中验证从一个表到另一个表的字段

在MySQL中验证从一个表到另一个表的字段,mysql,select,left-join,Mysql,Select,Left Join,问题是: 我有一个大约5000行的表,叫做imported_cities 我有一个大约80万行的表,称为邮政编码,包含邮政编码城市 我需要根据城市名称及其省份,根据邮政编码表中的城市验证导入的城市中的每个不同城市。见下表 如果他们完全匹配,是的,完全匹配。其余的城市都是手动验证的,我必须更新一列关于导入的城市和 将“导入的城市”中的城市和“邮政编码中的城市”并排输入第三个名为“导入的城市”的表中 我所尝试的: 向表添加索引并在下面进行查询。这需要永远…: 结果 id select_type ta

问题是:

我有一个大约5000行的表,叫做imported_cities

我有一个大约80万行的表,称为邮政编码,包含邮政编码城市

我需要根据城市名称及其省份,根据邮政编码表中的城市验证导入的城市中的每个不同城市。见下表

如果他们完全匹配,是的,完全匹配。其余的城市都是手动验证的,我必须更新一列关于导入的城市和 将“导入的城市”中的城市和“邮政编码中的城市”并排输入第三个名为“导入的城市”的表中

我所尝试的: 向表添加索引并在下面进行查询。这需要永远…:

结果

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ip index NULL  company_city 478 NULL 4221 Using index; Using temporary 
1 SIMPLE pc index NULL city_prov 160 NULL 765407 Using where; Using index; Using join buffer (Block...
-

-表postalcodes的表结构 -

-表导入城市的表结构 -

-表导入城市的表结构
任何帮助或建议都将不胜感激。谢谢。

您要获取信息的查询是:

SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
     postalcodes pc
     on LOWER(ip.destinationCity) = LOWER(pc.city)  and
        lower(ip.province) = lower(pc.province);
然而,这将有非常糟糕的性能。摆脱较低的成本将有助于:

SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
     postalcodes pc
     on(ip.destinationCity) =(pc.city)  and
       (ip.province) = (pc.province);
因为这样你就可以添加一个关于邮政城市,省的索引


如果无法使用remove lower,请更改表以添加新列,并将小写值放入这些列中。然后在新列上建立索引,并在联接中使用它们。

谢谢大家为我指明了正确的方向

根据您的建议进行了一些更改:

在destinationCity和destinationProvince列的导入城市表上添加了索引 在城市和省份ISO列的postalcodes表中添加了索引 由于字段ic.destinationCity已为大写,JOIN子句只有一侧大写 按省份限制查询性能的位置 最后一个SQL是:

SELECT DISTINCT pc.city, pc.provinceISO
FROM  postalcodes pc
    LEFT JOIN imported_cities ic
     ON upper(pc.city) = ic.destinationCity AND
     pc.provinceISO = ic.destinationProvince
     WHERE ic.destinationProvince = 'QC';
还有解释

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  pc  ref province    province    8   const   278115  Using index condition; Using temporary
1   SIMPLE  ip  ref destinationCity,destinationProvince destinationCity 386 func    1   Using index condition; Using where; Distinct

接下来,我可以在PHP上构造INSERT查询,并进行一次INSERT查询以在第三个表中插入所有等效的城市。谢谢大家。

此外,您的查询需要花费很长时间,因为它基本上是在pc上进行表扫描。您有大约800K行,它的数据量为765407,除了乘以它的ip(它的数据量为4221)之外……您必须添加适当的索引,连接on子句以正确地建立表之间的关系,和/或通过添加where子句参数来优化搜索……精确匹配在MySQL上不起作用。我已经尝试过这样做:选择ip.destinationCity,pc.city不为空,因为城市从导入的价格ip left加入二进制ip上的postalcodes pc.destinationCity=二进制pc.city和ip.destinationProvince=pc.province;但是查询花了2分钟多才返回1000行,现在运行该查询需要多长时间?这些表的大小会增长吗?还是它们是静态行?postalcodes每年增长一次,但不会太多。进口城市每年最多可以增长1000个,但一般来说,它们是静态表。查询需要1-3秒。足够好了。但是这个查询多久运行一次?现在1-3秒似乎已经足够了,但从规模上看,你需要减少几秒……同意,但当新城市导入时,查询每年运行4次。
SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
     postalcodes pc
     on LOWER(ip.destinationCity) = LOWER(pc.city)  and
        lower(ip.province) = lower(pc.province);
SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
     postalcodes pc
     on(ip.destinationCity) =(pc.city)  and
       (ip.province) = (pc.province);
SELECT DISTINCT pc.city, pc.provinceISO
FROM  postalcodes pc
    LEFT JOIN imported_cities ic
     ON upper(pc.city) = ic.destinationCity AND
     pc.provinceISO = ic.destinationProvince
     WHERE ic.destinationProvince = 'QC';
id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  pc  ref province    province    8   const   278115  Using index condition; Using temporary
1   SIMPLE  ip  ref destinationCity,destinationProvince destinationCity 386 func    1   Using index condition; Using where; Distinct