2010-03-23 20 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的事情) - 因此讓更有效的方式在服務器使用索引。因爲,正如人們已經指出的那樣,你應該考慮索引你的數據。