简化mysql查询

时间:2014-03-17 12:21:43

标签: mysql ruby-on-rails

存在包含数据和许多复杂表格的数据库。主表是位置。它有一个餐厅,餐厅有很多美食,有一个城市,城市有一个州。 我必须在几个表中编写查询从多个字段中搜索数据的内容。 我的问题是

SELECT DISTINCT
 locations.*
 FROM
 locations,
 restaurants,
 cities,
 states,
 cuisines
 WHERE
 locations.restaurant_id = restaurants.id
 AND locations.city_id = cities.id
 AND cities.state_id = states.id
 AND cuisines.restaurant_id = restaurants.id
 AND (
 restaurants.name LIKE '%miami%'
 OR cities.city LIKE '%miami%'
 OR cities.zip LIKE '%miami%'
 OR states.state LIKE '%miami%'
 OR states.state_code LIKE '%miami%'
 ) AND (restaurants.delivery_type = '1' OR restaurants.delivery_type = 0)
 AND (cuisines.`name` LIKE '%Japanese%')

我认为不是好方法。请帮助简化此查询。

2 个答案:

答案 0 :(得分:1)

你可以简化"通过使用表别名和正确的连接语法编写查询:

SELECT DISTINCT l.*
FROM locations l join
     restaurants r
     on l.restaurant_id = r.id join
     cities c
     on l.city_id = c.id join
     states s
     on c.state_id = s.id join
     cuisines cu
     on c.restaurant_id = r.id
WHERE (r.name LIKE '%miami%' OR
       c.city LIKE '%miami%' OR
       c.zip LIKE '%miami%' OR
       s.state LIKE '%miami%'
       s.state_code LIKE '%miami%'
      ) AND
      r.delivery_type in (0, 1) AND
      cu.`name` LIKE '%Japanese%';

此查询的性质使得优化非常困难。您正在使用完整的通配符搜索like。如果您正在寻找名称,那么您应该考虑全文索引并使用match而不是like。这也可以让您同时搜索多个列。 (缺点:你真的只能搜索完整的单词,所以"迈阿密"不匹配" Tamiami"。)

答案 1 :(得分:1)

请注意,由于字符串开头的通配符,此查询无法使用索引,因此效率低下...

 SELECT l.*
   FROM locations l
   JOIN restaurants r
     ON r.id = l.restaurant_id 
   JOIN cities c
     ON c.id = l.city_id
   JOIN states s
     ON s.id = c.state_id 
   JOIN cuisines u
     ON u.restaurant_id = r.id
  WHERE 
      ( r.name LIKE '%miami%'
     OR c.city LIKE '%miami%'
     OR c.zip LIKE '%miami%'
     OR s.state LIKE '%miami%'
     OR s.state_code LIKE '%miami%'
 )
    AND r.delivery_type IN(1,0)
    AND u.name LIKE '%Japanese%';