我遇到的性能问题太大了。我使用PHP脚本从数据库中获取数据并将其插入到另一个表中(该脚本仅在数据库上运行查询,后者粘贴到下一个数据以获取数据,然后INSERT
)。有两个表需要加入并输出结果(填写第三个表),但其中一个表有3.9M行数据,第二个表有416k行。问题是我必须在类型varchar上使用连接,因为这些表没有以任何方式连接(通过列“name”连接),因为它是它们唯一共同的列。该表的结构是这样的:大型表上的MySQL查询性能问题
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)
表的街道是一个有390万行的查询如下所示:
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
以查看它停止的位置,但它正在运行该查询2天的SELECT
,从未得到INSERT
部分。
*我已收录既有“名”列( s.name)',同时发布解释您的查询计划 –
感谢您的信息,“名称”列在字幕大小上有所不同,例如一条街道像“Balsta 300”,另一条是“balsta 301”,所以我必须使用LOWER()(或UPPER()w/e,它是一样的) – MirzaS
您不需要使用lower()或upper(),除非您的归档以_cs(区分大小写)或二进制 – user1844933