存储过程需要很长时间才能完成

2024-06-23 02:29:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我们有一个有2000行的csv文件和一个约200万行的数据库table1,还有一个有60000行的table2

我们需要根据csv文件中的参数从table1进行查询,因此csv中的每一行都应该执行一个select查询。最初,我们尝试在应用程序的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实际上是循环索引。由于MySQL服务器有2000次往返,因此需要很长时间才能完成。仅仅完成这些查询大约需要16个小时

因此,我编写了下面的SP以避免循环,只需调用此SP即可在MySQL server中执行循环:

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行的测试中,for基于循环的原始解决方案在317.6秒内完成,而存储过程仅为SP本身就用了321.5秒。为什么会发生这种情况,我如何优化它


Tags: andcsvfromdatebetweenwhereselectpoint