Using Unwind and Dumping Data in neo4j - Query Optimization

I am doing batch insertion to insert data in neo4j but my transaction is taking huge time as my database is increasing continuously also.

In my project, For only one case ,I am having more then 18,000 records which are meant to be stored in db and will have relationships with a Target node.
Each record will be stored as Friend Node

Relationships are like

Target_Node-[r:followed_by]->Friend_Node
Target_Node-[r:Friends_with]->Friend_Node
Target_Node-[r:Performs_Activity]->Friend_Node

My query executes for all the cases separately and the chances are very likely that there maybe all three relations between a Target and Friend Node.

I am sending 20 records per thread for a single insertion which unwinds over the array of records and checks if the records is already exists in Friend_Node or Target_Node, if not then create it as a Friend_Node and then assign relation to it; If the node already have relationship and a new relation is passed to the query then a new relation will also be added between the two nodes.

Also I do check in my query if a Record do have a Location property then I do create a Location Node and assign the relation with that also.

Note: create_rel variable can be Friends_with,Followed_by or Activity_p

My query is as follows

"""UNWIND [{id: "1235" , uid : "0"}] as user

            UNWIND """+ l +""" as c

            OPTIONAL MATCH (n:Target {id : c.id , uid : "0"})

            OPTIONAL MATCH (m:Friend {id : c.id , screen_name:c.screen_name, uid : "0"})

            WITH coalesce(n, m) as node,user,c // returns first non-null value

            CALL apoc.do.when(node is null, "MERGE (n:Friend {id:c.id, name:c.name, profile: c.profile, location:c.location, uid : user.uid}) RETURN n", '', {c:c,user:user}) YIELD value

            with coalesce(node, value.n) as y,user,c

            MERGE (u:Target {id: user.id , uid : user.uid})

            """+create_rel+"""

            foreach (sc in c.cityn | merge(cn:Location {location:sc.location, loc_lower : sc.loc_lower}) merge (y)-[:`located_at`]-(cn))

            """

Db sometimes gives TransientError error also.

Feedback is appreciated as I am a learner and will appreciate valuable suggestions.

Thanks in advance