2010-03-23 68 views
3

我有一个系统,由此用户可以查看他们已经订阅了单独的类别,以及那些在该地区可用它们默认属于英寸如何使此SQL查询更高效? PHP

因此,表如下所示: 分类 UsersCategories RegionsCategories

我查询分贝为自己区域内的所有类别,以及所有他们所订阅的各个类别。

我的查询如下:

 Select * FROM (categories c) 
     LEFT JOIN users_categories uc on uc.category_id = c.id 
     LEFT JOIN regions_categories rc on rc.category_id = c.id 
     WHERE (rc.region_id = ? OR uc.user_id = ?) 

至少我认为是这样的查询,我使用的是蛋糕的ORM层中产生,所以确切的一个是:

 $conditions = array(
          array("OR" => array (
           'RegionsCategories.region_id' => $region_id, 
           'UsersCategories.user_id' => $user_id 
          ) 
     )); 
     $this->find('all', $conditions); 

这圈速度非常慢(有时大约20秒左右,每桌大约有5000行)。我的设计在这里有错吗?

我怎样才能检索到这两个用户的各个类别和他们的区域内都在同一个查询,而不考虑它的年龄?

谢谢!

回答

2

确保categories.id,users_categories.category_id,users_categories.user_id,regions_categories.category_id和regions_categories.region_id列的所有索引。

+0

你是个明星,工作就像一个魅力。我可能应该知道这一点。 Ta v.much。 – 2010-03-23 20:34:02

+0

是啊,我已经查询从接近一分钟到十分之一秒的流逝索引正确的领域。很高兴工作! – jmans 2010-03-23 20:37:41

1

假设jmans的建议已经落实;

IIRC的MySQL查询只能使用一个索引的时间,所以,也可以是昂贵的,它可以更快地将它拆分成两个查询和UNION他们,使每个子查询中使用不同的指标

1

尝试这一个:

select * from 
(
select category_id from users_categories where user_id = ? 
union 
select category_id from region_categories where region_id = ? 
) as q 
inner join categories c on c.id = q.category_id 

我想它做同样的工作,但不使用或(这是避免与大多数的RDBMS的事情) - 因此让更有效的方式在服务器使用索引。因为,正如人们已经指出的那样,你应该考虑索引你的数据。