2013-01-22 52 views
1

我在各種解決方案中一直使用數據庫,但從未真正設計過它們。因此,我對SQL的更精細的點很新穎。我有一個有許多表格的數據庫,但是有兩個主要的表格: 項目 - 引用大量其他表格,用於不隨修訂而變化的數據 入口 - 引用許多其他表格,用於修改數據的其他表格 每個項目將因此具有一個或多個修訂版(以及所有相關數據)。MySQL查詢速度問題查看

我想爲視圖中的所有修訂(以及相應的項目)選擇所有數據。我已經構建一個查詢,如下所示:

CREATE VIEW Single_Query 
AS 
SELECT i.REF_CODE AS REF 
gp.GROUP_NAME AS Group 
v.VERSION_NUMBER AS Version 
GROUP_CONCAT(DISTINCT(cy.COUNTRY_DESCRIPTION) SEPARATOR ', ') AS Country 
ey.PUB_DATE AS Published 
GROUP_CONCAT(DISTINCT(ct.CONTRIBUTOR_NAME) SEPARATOR ', ') AS Author 
i.ISBN_CODE AS ISBN 
GROUP_CONCAT(DISTINCT CONCAT(cn.COMPONENT_NUMBER, _utf8', ',cn.COMPONENT_DESCRIPTION) SEPARATOR '; ') AS Contents 
ey.NOTES AS Notes 
i.PRICE AS Price 
cl.COLOUR_DESCRIPTION AS Colour 
FROM entry AS ey 
JOIN item AS i ON ey.ITEM_ID = i.ITEM_ID 
JOIN group AS gp ON i.GROUP_ID = gp.GROUP_ID 
JOIN version AS v ON ey.VERSION_ID = v.VERSION_ID 
JOIN link_country_item AS lci ON i.ITEM_ID = lci.ITEM_ID 
JOIN country AS cy ON lci.COUNTRY_ID = cy.COUNTRY_ID 
LEFT JOIN link_entry_contributor AS lec ON ey.ENTRY_ID = lec.ENTRY_ID 
LEFT JOIN contributor AS ct ON lec.CONTRIBUTOR_ID = ct.CONTRIBUTOR_ID 
JOIN contents AS cn ON i.ITEM_ID = cn.ITEM_ID 
JOIN colour AS cl ON ey.COLOUR_ID = cl.COLOUR_ID 
GROUP BY REF_CODE, VERSION_NUMBER 

這需要約29秒才能完成,只有少數的作品!但是,如果我運行腳本來爲項目數據(以及所有引用的數據)和條目數據(以及所有引用的數據)創建臨時表,然後從ITEM_ID上的單個JOIN中選擇2個臨時表中的整個批次,然後它需要不到半秒的時間才能完成。

請注意,還有很多其他引用的表(爲了清楚起見,我省略了它們)。

如果有幫助,項目表引用組,通過設置(通過many-many link_country_item表)和內容表。

條目表引用版本,貢獻者(通過many-many link_entry_contributor表)和顏色表。

問題是,我並不是真的想在所有時間使用臨時表,因爲我不能在視圖中使用它們(或者至少我沒有發現如何)。有沒有更好的方法來分解視圖中的SQL,以便在這種情況下運行得更快?

提前

伊恩

回答

0

非常感謝,我稍微調整了查詢​​順序,看看你對REF_CODE評論。所以你是正確的,最初的索引答案不會涵蓋你。但是,如果項目表位於主位置(如果該項目具有(REF_CODE,ITEM_ID)上的索引應該有助於性能,就像您正在啓動該表一樣)以及GROUP BY子句的相應索引。

CREATE VIEW Single_Query 
AS 
SELECT STRAIGHT_JOIN 
     i.REF_CODE AS REF 
     gp.GROUP_NAME AS Group 
     v.VERSION_NUMBER AS Version 
     GROUP_CONCAT(DISTINCT(cy.COUNTRY_DESCRIPTION) SEPARATOR ', ') AS Country 
     ey.PUB_DATE AS Published 
     GROUP_CONCAT(DISTINCT(ct.CONTRIBUTOR_NAME) SEPARATOR ', ') AS Author 
     i.ISBN_CODE AS ISBN 
     GROUP_CONCAT(DISTINCT CONCAT(cn.COMPONENT_NUMBER, _utf8', ',cn.COMPONENT_DESCRIPTION) SEPARATOR '; ') AS Contents 
     ey.NOTES AS Notes 
     i.PRICE AS Price 
     cl.COLOUR_DESCRIPTION AS Colour 
    FROM 
     item AS i 
     JOIN entry ey 
      ON i.ITEM_ID = ey.ITEM_ID 
      JOIN version AS v 
       ON ey.VERSION_ID = v.VERSION_ID 
      JOIN colour AS cl 
       ON ey.COLOUR_ID = cl.COLOUR_ID 
      LEFT JOIN link_entry_contributor AS lec 
       ON ey.ENTRY_ID = lec.ENTRY_ID 
       LEFT JOIN contributor AS ct 
        ON lec.CONTRIBUTOR_ID = ct.CONTRIBUTOR_ID 
     JOIN group AS gp 
      ON i.GROUP_ID = gp.GROUP_ID 
     JOIN link_country_item AS lci 
      ON i.ITEM_ID = lci.ITEM_ID 
      JOIN country AS cy 
       ON lci.COUNTRY_ID = cy.COUNTRY_ID 
     JOIN contents AS cn 
      ON i.ITEM_ID = cn.ITEM_ID 
    GROUP BY 
     REF_CODE, 
     VERSION_NUMBER 
+0

感謝您的回覆DRapp。感謝您花時間。我不確定我可以在REF_CODE和VERSION_ID的'Entry'表中創建一個索引,因爲REF_CODE沒有直接鏈接到'Entry'表 - 它鏈接到'Item'表,然後通過' Entry/Item'鏈接在視圖執行過程中。除非我誤解了答案... – user2001184

+0

@ user2001184,修改後的答案。 – DRapp

+0

太棒了!我修正了這些修改,現在查詢時間已經從29秒下降到幾乎瞬間。非常感謝您對這一次的所有幫助。我一定會記得將來應用這種結構。 :-) – user2001184