我的性能问题太大了。我正在使用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
部分。
答案 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