大型表上的MySQL查询性能问题

时间:2017-09-25 06:47:56

标签: php mysql join

我的性能问题太大了。我正在使用PHP脚本从数据库中获取数据并将其插入到另一个表中(该脚本只在DB上运行查询,我在下面粘贴以获取数据,然后INSERT)。我需要连接两个表并输出结果(填写第3个表),但其中一个表有3.9M行数据,第二个表有416k行。问题是我必须在类型varchar上使用join,因为表没有以任何方式连接(通过列“name”连接),因为它是它们共有的唯一列。表结构如下:

  TABLE streets
  id (PK, int), 
  name varchar(70), 
  postnrid (FK, int)

  TABLE csvstreets 
  id (PK, int),
  lat decimal(12,10),
  lng decimal(12,10),
  streetname varchar(70)

表道是具有3.9M行的表,查询如下所示:

 SELECT s.id, c.lat, c.lng FROM streets AS s JOIN csvstreets AS c ON LOWER(s.name) = LOWER(c.streetname) 

查询连续运行了2天,但没有完成,所以我不得不取消它。我已在两个表上索引了两个“名称”列。在对查询执行EXPLAIN时,它会输出:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'c', 'ALL', NULL, NULL, NULL, NULL, '416240', ''
'1', 'SIMPLE', 's', 'index', NULL, 'name', '73', NULL, '3890226', 'Using where; Using index; Using join buffer (flat, BNL join)'

看起来“csvstreets”表没有使用我为它制作的索引。我可以使用任何建议,因为我已经尝试了一些我可以找到的用于提高varchar连接性能的东西。 此外,我无法限制结果输出,因为我需要它返回的所有数据(大约380k)。 我在脚本中添加了echo以查看它停止的位置,但它只运行SELECT查询2天,从未进入INSERT部分。

1 个答案:

答案 0 :(得分:0)

摆脱lower()s。它保持联接不使用您的索引,除非您设置了区分大小写的排序规则,否则您不需要它。当然没有必要区分“Balsta 300”和“Balsta 301”。

如果之后您的查询仍未完成,请显示以下所有内容的输出:

show create table streets 
show create table csvstreets
explain SELECT s.id, c.lat, c.lng FROM streets AS s JOIN csvstreets AS c ON s.name=c.streetname