2013-08-05 31 views
0

我有500萬行的信息表,我想找回過去的10行的兩個用戶的交談優化查詢SQL傳令

+---------------------------------------------------------------+ 
|       messages        | 
+---------------------------------------------------------------+ 
| message_id | id_sender | id_dest | subject | message | time | 
+---------------------------------------------------------------+ 

這是我可以優化它的查詢?

SELECT * 
FROM 
    (SELECT message 
    FROM messages 
    WHERE (id_sender = id1 AND id_dest = id2) or 
      (id_dest = id1 AND id_sender = id2) 
    ORDER BY message_id DESC 
    LIMIT 10) AS ttbl 
ORDER BY message_id ASC 

謝謝!

我有id_sender id_dest指數和message_1d上優化

更新

+1

你想優化什麼?速度?你有索引嗎?這是爲postgresql或MySQL?你已經標記了兩個,但它看起來像mysql輸出。 – bma

+0

包含您的查詢的解釋計劃。你在什麼版本的PostgreSQL? – Kuberchaun

+0

基於或分解的'||'運算符,此查詢僅適用於mysql,因此刪除postgresql標記。 –

回答

1

這是您的查詢:

SELECT * 
FROM (SELECT * 
     FROM messages 
     WHERE (id_sender = id1 AND id_dest = id2) or 
      (id_dest = id1 AND id_sender = id2) 
     ORDER BY message_id DESC 
     LIMIT 10 
    ) ttbl 
ORDER BY message_id ASC; 

message(id_sender, id_dest, message_id)創建索引。這將允許使用索引來滿足內部查詢。

我不擔心* - 在操作查詢中使用*是不好的做法,因爲底層表可能會更改。爲此,您正在選擇10條記錄。引擎將不得不查找10條記錄來獲取所有字段並對它們進行排序(第一類應該由索引處理)。對10條記錄進行排序通常不是什麼大問題。

3

首先說明,這是一個很多比更多地參與如何優化呢?

其次,一些想法:

  • 不要使用SELECT *如果是沒有必要的。只需帶回所需的字段。
  • 這建立了第一個。建立覆蓋指數。這意味着如果在查詢的任何地方中使用了字段a, b, c,那麼您可以在表上的a, b, c上建立索引。這將允許數據庫讀取索引頁面,而不必從數據頁面進行查找,加載和讀取。
+0

涵蓋的索引不存在於所有版本的PostgreSQL中,需要9.2或更高版本。當然,根據標籤,我們並不知道查詢實際上定位了哪個系統。 – Kuberchaun

+0

@JustBob,非常感謝你的澄清! –

1

這裏有一對夫婦爲您WHERE條款的其他選項,你可能會希望比較的性能:

WHERE id1 IN (id_sender, id_dest) 
AND id2 IN (id_sender, id_dest) 

能否id_sender = id_dest?如果沒有,那麼你可以刪除3號線折以下WHERE條款

WHERE id_sender IN (id1, id2) 
AND id_dest IN (id1, id2) 
AND id_sender <> id_dest 
0

沒有看到解釋計劃,我只能猜測的問題。我的猜測是,你最大的表現是OR。嘗試用聯合替換OR:

SELECT * 
FROM (SELECT * 
     FROM messages 
     WHERE id_sender = id1 
     AND id_dest = id2 
     ORDER BY message_id DESC 
     LIMIT 10 

     UNION 

     SELECT * 
     FROM messages 
     WHERE id_dest = id1 
     AND id_sender = id2 
     ORDER BY message_id DESC 
     LIMIT 10 
    ) ttbl 
ORDER BY message_id ASC 
LIMIT 10; 
+0

您的查詢有聯盟限制錯誤 –