Stored Procedure is taking very long to complete
Here's one suggestion:

CREATE TEMPORARY TABLE csv
( i int not null
, c1 ... not null
, c2 ... not null
, c3 ... not null
, c4 ... not null )


Load the csv file into the temporary table, and use a join to get the result.

SELECT csv.i 
   table1.c1, 
   table1.c2, 
   csv.st_dist_spere, 
   ST_Distance_Sphere(point(csv.c2[i], csv.c3[i]),  
                      point(table1.c3, table1.c4)) * 0.2 AS length, 
   table1.c5 
FROM   table1
CROSS JOIN csv  
WHERE  table1.c1 IN (
                 SELECT DISTINCT table2.c1 
                 FROM      table2 
                 LEFT JOIN table2.c1=table3.c1 
                 WHERE table2.c2=1 
                 AND   table2.c3 BETWEEN 1000 AND 2000
HAVING length &lt; csv.c4 
   AND    table1.c5 BETWEEN date(start_date) AND date(end_date) 
ORDER BY csv.i, table.c1


I would then look at the IN predicate (I'll assume this is what it is supposed to be):

SELECT DISTINCT table2.c1 
FROM      table2 
LEFT JOIN table3
    ON table2.c1=table3.c1 
WHERE table2.c2=1 
  AND table2.c3 BETWEEN 1000 AND 2000 


The outer join against table3 can be eliminated (a smart optimizer should realize this, but I don't know if this is implemented in MySQL):

SELECT DISTINCT table2.c1 
FROM      table2 
WHERE table2.c2=1 
  AND table2.c3 BETWEEN 1000 AND 2000


This leaves us with:

SELECT csv.i 
   table1.c1, 
   table1.c2, 
   csv.st_dist_spere, 
   ST_Distance_Sphere(point(csv.c2[i], csv.c3[i]),  
                      point(table1.c3, table1.c4)) * 0.2 AS length, 
   table1.c5 
FROM   table1
CROSS JOIN csv  
WHERE  table1.c1 IN (
                 SELECT DISTINCT table2.c1 
                 FROM      table2 
                 WHERE table2.c2=1 
                 AND   table2.c3 BETWEEN 1000 AND 2000
       )
HAVING length &lt; csv.c4 
   AND    table1.c5 BETWEEN date(start_date) AND date(end_date) 
ORDER BY csv.i, table.c1


Next step, is trying to replace the IN PREDICATE with a JOIN:

SELECT csv.i 
   table1.c1, 
   table1.c2, 
   csv.st_dist_spere, 
   ST_Distance_Sphere(point(csv.c2[i], csv.c3[i]),  
                      point(table1.c3, table1.c4)) * 0.2 AS length, 
   table1.c5 
FROM   table1
CROSS JOIN csv  
JOIN ( SELECT DISTINCT table2.c1 
       FROM      table2 
       WHERE table2.c2=1 
       AND   table2.c3 BETWEEN 1000 AND 2000
     ) as X
   ON X.c1 = table1.c1
HAVING length &lt; csv.c4 
   AND    table1.c5 BETWEEN date(start_date) AND date(end_date) 
ORDER BY csv.i, table.c1 


It may be advantageous to push the range predicate into table1 before doing the cross join:

SELECT csv.i 
   table1.c1, 
   table1.c2, 
   csv.st_dist_spere, 
   ST_Distance_Sphere(point(csv.c2[i], csv.c3[i]),  
                      point(table1.c3, table1.c4)) * 0.2 AS length, 
   table1.c5 
FROM (  
    select ... from table1 
    where table1.c5 BETWEEN date(start_date) AND date(end_date)
) as table1
CROSS JOIN csv  
[....]