2012-04-10 129 views
1

我有以下表,MySQL的派生表,性能,替代

  1. link_books_genres,*表結構 - > book_id,genre_id *
  2. 流派,*表結構 - > genre_id,GENRE_NAME *

給定一組book_ids的,我想形成如下的結果,

result_set structure -> genre_id, genre_name, count(book_id). 

我寫此查詢,

SELECT one.genre_id, 
     one.genre_name, 
     two.count 
FROM genres as one,(SELECT genre_id, 
        count(book_id) as count 
        FROM link_f2_books_lists GROUP BY genre_id) as two 
WHERE one.genre_id = two.genre_id; 

我不知道這是最好的解決辦法,但我想這是可能的話或進行優化,如果它是良好的,有效的。

P.S.它在軌道上使用ruby完成,所以任何軌道導向的方法也可以。

回答

2

您的查詢不使用SQL-92 JOIN語法,而是使用較舊的隱式連接語法。現在是時候(20年了),你應該開始使用它。

使用關鍵字COUNT作爲別名也不是很好。你可以使用cntbook_count代替:

SELECT one.genre_id, 
     one.genre_name, 
     two.cnt 
FROM 
     genres AS one 
    INNER JOIN 
     (SELECT genre_id, 
       COUNT(book_id) AS cnt 
     FROM link_f2_books_lists 
     GROUP BY genre_id 
     ) AS two 
      ON one.genre_id = two.genre_id ; 

的MySQL通常是COUNT(*)有點快,所以如果book_id不能NULL,改變COUNT(book_id)COUNT(*)將是一個小的性能提升。


當然,你可以重寫加入不派生表:

SELECT one.genre_id, 
     one.genre_name, 
     COUNT(*) AS cnt 
FROM 
     genres AS one 
    INNER JOIN 
     link_f2_books_lists AS two 
      ON one.genre_id = two.genre_id 
GROUP BY one.genre_id ; 

在這兩個版本,你可以爲了流派改變INNER JOINLEFT OUTER JOIN沒有任何書籍(0計數)中顯示。但是,請使用COUNT(two.book_id)而不是COUNT(*),以獲得正確的結果。

以上版本(和你)將不包括那些類型(這是一個很好的理由來使用JOIN語法,所需要的變化是非常簡單的。請嘗試與您的WHERE版本!)


LEFT JOIN版本也可以寫成這樣:

SELECT one.genre_id, 
     one.genre_name, 
     (SELECT COUNT(*) 
     FROM link_f2_books_lists AS two 
     WHERE one.genre_id = two.genre_id 
     ) AS cnt 
FROM 
     genres AS one ; 

關於業績,沒有什麼比測試ÿ更好我們自己。這一切都取決於你使用的MySQL版本(新版本會有更好的優化器,可以通過更多的選項來選擇來創建執行計劃,可能它會識別不同的版本等效),表的大小,索引,數據的分佈(有多少種不同的流派?平均每種流派有多少本書?等等),你的記憶(和其他MySQL)設置,以及可能現在我忘記的其他許多因素。

一個建議是,在大多數情況下,對於所有版本,(genre_id, book_id)上的索引將是有用的。

作爲一般性建議,在多對多表上同時使用(genre_id, book_id)(book_id, genre_id)索引通常是很好的做法。

+0

非常感謝。我將與Inner join並數(*)。我計劃在我的數據庫上安裝sphinxsearch。你怎麼看? – beck03076 2012-04-11 14:13:27

+0

如果你想全文搜索,是的,有各種產品可以與MySQL合作:Sphinx,Lucene,Solr。檢查這個問題:[選擇一個獨立的全文搜索服務器](http://stackoverflow.com/questions/1284083/choosing-a-stand-alone-full-text-search-server-sphinx-or-solr )或做你自己的研究。 – 2012-04-11 14:19:00

+1

@ beck03076:但這個問題沒有解決。如果您有任何問題(針對數據庫),這些問題太模糊,無法發佈到SO或尋找意見,您可以隨時在[DBA聊天室]找到某人(http://chat.stackexchange.com/rooms/179/the-hello) – 2012-04-11 14:41:50

0
SELECT one.genre_id, one.genre_name, count(two.book_id) 
FROM genres as one, link_books_genres as two 
WHERE one.genre_id=two.genre_id 
GROUP BY genre_id