0
votes

I have tried hard to optimize the following query but can't get it down to under two minutes - is this expected? Is there any way I can speed things up. I have added indexes and used WITH wherever possible.

match (md:MarketingDetail {Status: 'Live'})
with md limit 10
match (md) -[:Has_Area]-> (a:Area)
with md, a
match (ss:SavedSearch) -[:Has_Area]->(a)
with md, ss match
(md) -[:Has_Trade] -> (st:SectorTrade) <-[:Has_Trade]- (ss)
where ((md.FreeholdTenure ='Freehold'
and ss.FreeholdTenure = 'true'
and (md.FreeholdSearchPrice >= ss.PriceFrom
or md.FreeholdSearchPrice is null)
and (md.FreeholdSearchPrice <= ss.PriceTo
or md.FreeholdSearchPrice is null))
or (md.LeaseholdTenure is not null
and ss.LeaseholdTenure = 'true'
and (md.LeaseholdSearchPrice >= ss.PriceFrom
or md.LeaseholdSearchPrice is null)
and (md.LeaseholdSearchPrice <= ss.PriceTo
or md.LeaseholdSearchPrice is null)))
return count(ss)

Here is the profile of the above query -

Query Profile

Thanks!

2
Can you share your PROFILE output (expand all boxes and share the screenshot)? You don't need the WITH statements after the first.Michael Hunger
I have added the results of the PROFILE to the question above - thanks!Miloandmilk

2 Answers

0
votes

Without knowing anything about your graph and its structure/size, it's hard to know exactly how to query it efficiently. At the moment your query seems to match every md and ss combination before querying for the desired pattern, this may or may not be the best approach depending on the graph, but I've tried an alternative below.

You can put PROFILE before a query to see how it executed and look for bottlenecks. Could you post the results of this, as well as your indexes by running :schema??

MATCH (md:MarketingDetail {Status: 'Live'})
WHERE 
  (
    md.FreeholdTenure ='Freehold'
    OR md.LeaseholdTenure is not null
    OR md.LeaseholdSearchPrice is null
    OR md.LeaseholdSearchPrice is null
  )
WITH md LIMIT 10
match (md) -[:Has_Area]-> (a:Area)<-[:Has_Area]-(ss:SavedSearch)-[:Has_Trade]->(st:SectorTrade)-[:Has_Trade]->(md)
where
  AND
  (
    md.FreeholdTenure ='Freehold'
    and ss.FreeholdTenure = 'true'
    and (md.FreeholdSearchPrice >= ss.PriceFrom or md.FreeholdSearchPrice is null)
    and (md.FreeholdSearchPrice <= ss.PriceTo or md.FreeholdSearchPrice is null)
  )
  or (
    md.LeaseholdTenure is not null
    and ss.LeaseholdTenure = 'true'
    and (
      md.LeaseholdSearchPrice >= ss.PriceFrom
      or md.LeaseholdSearchPrice is null
    )
    and (
      md.LeaseholdSearchPrice <= ss.PriceTo
      or md.LeaseholdSearchPrice is null
    )
  )  
return count(ss)
0
votes

According to your PROFILE, you do not have an index for :MarketingDetail(Status), which is very important to have for your query, since that is needed by the first MATCH.

In addition, restructuring your query (possibly in the way @DonWeldon suggests) should be helpful.