简体   繁体   中英

NEO4J Cypher query slow

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 -

查询资料

Thanks!

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM