2010-08-20 47 views
2

我有時間太長執行即使在小表的基本查詢(< 100,000行):加快與加盟,其中,組通過查詢,統計

select images.classification, count(boxes.id) 
from images 
join boxes on images.id = boxes.image_id 
where boxes.round = 0 
group by images.classification; 

我有箱子指數.round,boxes.image_id和images.classification(在此查詢中只有varchar)。在boxes.id和images.id上的主鍵。解釋表明它正在利用boxes.round索引。額外的是:Using where; Using temporary; Using filesort

是否有可能加快此查詢?怎麼樣?

重要的是,服務器是MySQL 5.1的所有MyISAM表。

(這個問題是類似於How to speed up "select count(*)" with "group by" and "where"?


完全解釋輸出:

mysql> explain select images.classification, count(boxes.id) from images join boxes on images.id = boxes.image_id where boxes.round = 0 group by images.classification; 

| 1 | SIMPLE  | boxes | ref | ix_boxes_image_id,ix_boxes_round | ix_boxes_round | 5  | const      | 64162 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | images | eq_ref | PRIMARY          | PRIMARY    | 4  | vatic.boxes.image_id |  1 |            | 
+0

你可以發佈'EXPLAIN'的輸出嗎? – Piskvor 2010-08-20 18:50:38

+0

@Piskvor,補充說。 – carl 2010-08-20 18:54:27

+0

謝謝,這是一個相當重要的數據。 – Piskvor 2010-08-20 19:56:01

回答

2

(images.id, images.classification)添加索引 - 這應該給你

  • 爲加入一個指標。你已經有一個通過主鍵,但你還可以得到:
  • 同樣可作爲一個覆蓋索引
  • 爲分組條款

同樣在(boxes.image_id,boxes.round)添加索引相同的索引的索引:

  • 指數爲JOIN
  • 覆蓋指數爲COUNT(見下文)

關於COUNT子句:如果在boxes.id(假設不是)中沒有NULL s,則可以用COUNT(boxes.image_id)替換它,以便我們可以從prev的索引中獲得更多的用處。段。

再次,驗證與EXPLAIN,但我會說這些步驟應該讓你更好的執行計劃。

+1

附加說明:'使用where' - 無法從索引中找出所有條件 - 需要查看合適的表以評估WHERE(較慢); '使用臨時的' - 需要爲此創建一個臨時結果表(將使用大表緩慢); '使用filesort' - 臨時表太大而無法放入內存,將其交換到磁盤(磁盤訪問速度慢) – Piskvor 2010-08-20 20:06:03

0

添加一個索引images.id

+1

images.id是一個主鍵。 – carl 2010-08-20 18:52:59

0

將images.classification而不是varchar使用整數是否可行?

+0

這可能是可能的,但是當這個查詢生效時,我需要大量遷移。 – carl 2010-08-20 18:56:55

+0

好點,INT通常比VARCHAR更快。 – Piskvor 2010-08-20 19:59:06