2012-11-27 64 views
7

我有以下查詢如何提高COUNT(DISTINCT field1)... GROUP BY field2的性能?

EXPLAIN SELECT COUNT(DISTINCT ip_address) as ip_address, exec_date 
    FROM requests 
    GROUP BY exec_date; 

id select_type table  type  possible_keys key   key_len ref  rows Extra 
1 SIMPLE  requests range  NULL   daily_ips 263  NULL 488213 Using index for group-by (scanning) 

隨着覆蓋索引daily_ips

Table  Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment 
requests 1   daily_ips 1    exec_date A   16   NULL  NULL YES BTREE  
requests 1   daily_ips 2    ip_address A   483492  NULL  NULL YES BTREE  

有沒有什麼辦法可以進一步優化此查詢?

Using index for group-by (scanning)是什麼意思?這是否意味着整個GROUP BY子句完全是從索引完成的,而COUNT(DISTINCT ip_address)部分則不是?

回答

3

根據您提供的數據,我看不到任何方式可以進一步優化查詢。

至於你的後續問題,MySQL的描述解釋輸出Using index for group-by手冊頁說:

類似於使用索引表訪問方法,使用指數組的指示是,MySQL發現了一個索引可用於檢索GROUP BY或DISTINCT查詢的所有列,而無需對實際表進行任何額外的磁盤訪問。此外,索引以最有效的方式使用,因此對於每個組,只有少數索引條目被讀取。有關詳情,請參閱Section 8.13.10, 「GROUP BY Optimization」

您的索引特別適合加快查詢速度。由於只有索引字段被選中(查詢中的每一列也出現在索引中),因此所有相關數據都出現在索引中,MySQL甚至可能根本不需要打表。

如果執行查詢就像在google上執行搜索,想象不必點擊任何鏈接的網站,因爲您直接在搜索結果中找到了您要查找的信息 - 這有點像什麼需要掃描表格數據就好。這裏有一些關於how MySQL uses indexes的更多信息:

在某些情況下,可以優化查詢來檢索值而不用諮詢數據行。 (爲查詢提供所有必要結果的索引稱爲covering index。)如果查詢僅使用表中的數字爲列的某些鍵的最左前綴的列,則可以從索引樹中檢索所選值更大的速度:

SELECTkey_part3FROMtbl_nameWHEREkey_part1 = 1

+1

感謝Danny,出於好奇,有沒有什麼辦法可以判斷'使用索引for group-by(掃描)'是指應用於GROUP BY或DISTINCT子句的索引? – user784637

+0

由於'DISTINCT'只是[GROUP BY'的特例(http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html),並且由於兩列來自同樣的表格,相同的索引,我真的不確定。 –

0

您你能對象化:

Objectify ofy = ObjectifyService.begin(); 查詢查詢= ofy.query(這裏是類名稱.class).filter(「表中的列名」,要查詢的值).list();

在此之前,您可能需要爲Objectify添加jar。

相關問題