简体   繁体   中英

SQL query taking too long (LEFT OUTER JOIN)

I have been testing a SQL query for a search propose to get data from the columns 'fleet', 'trips', 'bookings', 'agencies' and 'persons'.

The problem is that this query is taking too long (2min) to complete. I tryed to use 'WHERE' and/OR 'INNER JOIN' and the query time is reduced to a few milliseconds, but it doesn't give me all the results I want. For instance, there are some entries from 'trips' that don't have 'bookings' associated or some 'bookings' entries that don't have 'persons' associated. That's why I need to use the LEFT OUTER JOIN, but this is making the query very slow.

I believe that I have some efficiency problem in this syntax, but I can't figure out what it is.

I want the result to be like this:

bid     tid     tstatus    timestamp    start   end   gname pname   fname       blockedtrips  tcreator  bcreator    baname  taname
NULL    2736    1          1468022400   540     720   NULL  NULL    Little Boy  1             9         NULL        NULL    Conscience Dauphin
NULL    2737    1          1468022400   540     720   NULL  NULL    Moby Dick   1             9         NULL        NULL    Conscience Dauphin

My query is the following:

SELECT 
 bookings.id AS bid, trips.id AS tid, trips.id_status AS tstatus,
 trips.timestamp, trips.start, trips.end, bookings.groupname AS gname,
 persons.name AS pname, fleet.name AS fname, trips.blockedtrips AS blockedtrips,
 trips.id_creator AS tcreator, bookings.id_creator AS bcreator,
 (SELECT name FROM agencies WHERE deleted=false AND id=bookings.id_agency) AS baname,
 (SELECT name FROM agencies WHERE deleted=false AND id=trips.id_agency) AS taname
FROM
 trips OUTER LEFT JOIN fleet ON fleet.id = trips.id_fleet AND fleet.deleted=false AND trips.deleted=false
 LEFT OUTER JOIN bookings ON trips.id = bookings.id_trip AND bookings.deleted=false
 LEFT OUTER JOIN persons ON bookings.id = persons.id_booking AND persons.deleted=false
  AND ( 
   (SELECT name FROM agencies WHERE deleted=false AND id=bookings.id_agency) LIKE '%conscience%'
   OR (SELECT name FROM agencies WHERE deleted=false AND id=trips.id_agency) LIKE '%conscience%'
   OR bookings.groupname LIKE '%conscience%'
   OR persons.name LIKE '%conscience%'
   OR fleet.name LIKE '%conscience%'
  )
  ORDER BY trips.timestamp
  DESC LIMIT 0,100

QUERY UPDATED:

SELECT 
     bookings.id AS bid, trips.id AS tid, trips.id_status AS tstatus,
     trips.timestamp, trips.start, trips.end, bookings.groupname AS gname, 
     persons.name AS pname, fleet.name AS fname, trips.blockedtrips AS blockedtrips, 
     trips.id_creator AS tcreator, bookings.id_creator AS bcreator, 
     bagency.name AS baname, tagency.name AS taname 
FROM fleet 
     LEFT JOIN trips ON fleet.id = trips.id_fleet AND fleet.deleted=false AND trips.deleted=false
     LEFT JOIN agencies AS tagency ON tagency.id = trips.id_agency AND tagency.deleted=false
     LEFT JOIN bookings ON trips.id = bookings.id_trip AND bookings.deleted=false
     LEFT JOIN agencies AS bagency ON bagency.id = bookings.id_agency AND bagency.deleted=false  
     LEFT JOIN persons ON bookings.id = persons.id_booking AND persons.deleted=false
WHERE
     bagency.name LIKE '%conscience%' 
     OR tagency.name LIKE '%conscience%' 
     OR bookings.groupname LIKE '%conscience%' 
     OR persons.name LIKE '%conscience%' 
     OR fleet.name LIKE '%conscience%'
ORDER BY trips.timestamp DESC 
LIMIT 0,100

you could join the tables with agencies instead of using multiple subqueries for it, this should give you same result, try it hope it is helpful:

SELECT 
 bookings.id AS bid, trips.id AS tid, trips.id_status AS tstatus,
 trips.timestamp, trips.start, trips.end, bookings.groupname AS gname,
 persons.name AS pname, fleet.name AS fname, trips.blockedtrips AS blockedtrips,
 trips.id_creator AS tcreator, bookings.id_creator AS bcreator,
 ag1.name AS baname,
 ag2.name AS taname
FROM
 trips OUTER LEFT JOIN fleet ON fleet.id = trips.id_fleet AND fleet.deleted=false AND trips.deleted=false
 LEFT OUTER JOIN bookings ON trips.id = bookings.id_trip AND bookings.deleted=false
 LEFT OUTER JOIN persons ON bookings.id = persons.id_booking AND persons.deleted=false
 left join agencies ag1 on ag1.id=bookings.id_agency and ag1.deleted=false and ag1.name  LIKE '%conscience%'
 left join agencies ag2 on ag2.id=trips.id_agency ag2.deleted=false
  where 
   ag1.name LIKE '%conscience%'
   OR ag2.name  LIKE '%conscience%'
   OR bookings.groupname LIKE '%conscience%'
   OR persons.name LIKE '%conscience%'
   OR fleet.name LIKE '%conscience%'
  ORDER BY trips.timestamp
  DESC LIMIT 0,100

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