2015-12-02 94 views
0

我有一個特定的結構,我想要重寫,以便它運行更快的MySQL查詢。目前運行速度很慢,需要大約255秒才能執行。如果我刪除了連接,它將在10秒內運行<。它的目的是一次從表A獲得100行記錄,只要用戶希望看到更多的行。製作限制X,Y MySQL查詢連接運行更快

我懷疑這個查詢花了很長時間,因爲它在連接上發現的不止是前100行。這是真的嗎?如果是這樣,有沒有辦法在從主表中獲取行之後重寫查詢來完成連接?

數據來自'主'表A,它具有日期時間字段(START_TIME)和多個帶字符串值的表的外鍵(表,B,C,D)。

表A有250萬行。表B有600K行。 表A在START_TIME上有一個索引。表B有一個ID值的索引。

這是查詢的基本形式。我不想在START_TIME上設置上限,因爲我總是希望從查詢中獲取100條記錄。我使用了少於100條記錄的響應來指示數據庫中沒有更多記錄。

SELECT 
    A.START_TIME, A.F1, A.F2, B.STRING 
FROM 
    A 
    INNER JOIN B ON A.B_ID = B.ID 
WHERE 
    A.START_TIME >= '2015-03-22 05:23:44' 
LIMIT 0, 100; 

這裏是解釋。對不起,格式爲:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra 
1, SIMPLE, B, index, PRIMARY, FSN, 95, , 1, Using index; Using temporary; Using filesort 
1, SIMPLE, A, ref, A_ix_B_ID,A_ix_C, A_ix_B_ID, 4, ag100_a$$burnaby.B.ID, 2, Using where 
+0

您可以使用'ctrl-k'將文本格式設置爲代碼。 –

+0

現在你必須嘗試每次添加一個表格http://importblogkit.com/2015/05/how-do-you-eat-an-elephant/你應該嘗試每一個選擇類型索引 –

+0

這裏一次添加一個表的結果:僅表A:8.7秒,表A和B:255秒。問題仍然存在,我的原始問題仍然存在:是否有一種重構此查詢的方式,以便在從表A檢索記錄之後完成連接。這是非常重要的,因爲這是一個非常常見的查詢。 – user3341576

回答

0

你必須提供解釋計劃,以便我們可以幫助你更好。

https://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html

但是對於你的描述,你仍然需要索引。

表A旁START_TIME爲每個索引需要加入字段B_id, C_id and D_id,也許使用複合指數對於所有4個可變會更好

CREATE INDEX A_Bid_idx ON A (B_id); 
CREATE INDEX A_Cid_idx ON A (C_id); 
CREATE INDEX A_Did_idx ON A (D_id); 

OR 

CREATE INDEX A_Full_idx ON A (B_id,C_id, D_id, START_TIME); 

表C和d還需要C.ID and D.ID索引。如果他們使用的複合指數

(C.ID, C.STRING) and 
    (D.ID, D.STRING) 

    CREATE INDEX C_id_idx ON C (ID); 
    CREATE INDEX D_id_idx ON D (ID); 

    OR 

    CREATE INDEX C_id_string_idx ON C (ID, STRING); 
    CREATE INDEX D_id_string_idx ON C (ID, STRING); 

這樣分貝不必須做一個查找找到asociated的ID

+0

關於更好的解釋,你還想知道什麼?但是,在發現100條記錄之後,通過對連接進行的最大節省時間不是最大的節省時間嗎?我會添加上面建議的索引,然後重試。 – user3341576

+0

正如我所說,你仍然需要一些索引。你必須向我們展示解釋計劃,看看問題出在哪裏http://use-the-index-luke.com/sql/explain-plan/mysql/getting-an-execution-plan –

+0

請幫助我。我不知道要給你什麼其他信息。 – user3341576

0
SELECT A.START_TIME, A.F1, A.F2, 
     (SELECT STRING 
      FROM B 
      WHERE A.B_ID = B.ID 
    ) AS String 
    FROM A 
    WHERE A.START_TIME >= '2015-03-22 05:23:44' 
    ORDER BY START_TIME 
    LIMIT 0, 100; 

可能會跑得更快的字符串值,甚至會更好。從A'被迫'使用INDEX(START_TIME)

請提供SHOW CREATE TABLE這兩個表;我想檢查數據類型等。