我们有一个csv
个文件,包含2000行,一个数据库table1
约有200万行,另一个table2
包含60000行。
我们需要根据csv文件中的参数从table1
进行查询,因此csv
中的每一行都应执行一个选择查询。最初,我们尝试在应用程序中的for loop
内执行以下查询:
SELECT table1.c1, table1.c2, ST_Distance_Sphere(point(csv.c2[i], csv.c3[i]), point(table1.c3, table1.c4))*0.2 AS length, table1.c5 FROM table1
WHERE table1.c1 IN (
SELECT DISTINCT table2.c1 FROM table2 LEFT JOIN table2.c1=table1.c1
WHERE table2.c2=1 AND table2.c3 BETWEEN 1000 AND 2000
) HAVING length < csv.c4[i]
AND table1.c5 BETWEEN date("start_date")
AND date("end_date") ORDER BY table.c1
csv.c1[i]
i
实际上是循环索引。由于2000次往返MySQL服务器,需要很长时间才能完成。通过查询大约需要16个小时。
所以,我编写了下面的SP以避免循环,只需调用此SP就可以在MySQL服务器中进行循环:
CREATE PROCEDURE sp()
BEGIN
DECLARE arg0 VARCHAR(255);
DECLARE arg1 FLOAT;
DECLARE arg2 FLOAT;
DECLARE arg3 FLOAT;
DECLARE cur1 CURSOR FOR SELECT * FROM csv_based_table;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO arg0, arg1, arg2, arg3;
SELECT col0, col1, ST_Distance_Sphere(point(arg1, arg2),point(col3,col4))*2 AS length, arg0 FROM important_table1 WHERE
col0 IN (
SELECT DISTINCT c0 FROM important_table2 LEFT JOIN c0 ON col0 = c0 WHERE c1=1 and c2 BETWEEN 1000 AND 2000)
HAVING distance < arg3 AND col5 BETWEEN date("start_date") AND
date("end_date") ORDER BY arg0, col0;
END LOOP;
CLOSE cur1;
END;
因此,我们不是使用csv文件,而是为该csv文件创建一个数据库表并运行上面的存储过程。问题是这比原来的2000迭代循环要慢。在超过100 csv行的测试中,基于循环的原始解决方案以 317.6秒结束,而存储过程仅为SP本身 321.5秒。为什么会发生这种情况?如何优化呢?