2011-02-22 107 views
4

我已經創建了一個sql表,我在磁盤上創建了索引文件。 桌上有超過100萬條記錄。 我已經添加了ext和size的索引,但是它仍然需要一分鐘才能執行這個查詢,它告訴我ext使用的空間量。 如何提高此選擇的性能?mysql:我該如何提高這個mysql select語句的性能

select ext, 
    ROUND((sum(size)/(1073741824))) as TotalSizeGB, 
    count(*) as Count 
    from fileindex 
group by ext 
order by TotalSizeGB desc; 

Explain輸出:

|| *id* || *select_type* || *table* || *type* || *possible_keys* || *key* || *key_len* || *ref* || *rows* || *Extra*          || 
|| 1 || SIMPLE  || fileindex || index || _NULL_   || ext || 27  || _NULL_ || 1892234 || Using index; Using temporary; Using filesort || 
+0

你能告訴我們的查詢計劃嗎?使用EXPLAIN http://dev.mysql.com/doc/refman/5.5/en/explain.html – 2011-02-22 18:41:19

+0

我不認爲你可以改善它,因爲它加載**全部**表中的數據。 – Augusto 2011-02-22 18:49:53

+0

@augusto除非在`ext`上缺少可用於執行分組的索引 – 2011-02-22 18:52:01

回答

2

寫入的查詢總是會打到表中的每一行 - 所以確實有一個限制它能夠執行的速度。如果你真的希望這個結果很快返回,你可能想要添加另一個表來保持每個ext的總大小,並且每當在主表上進行操作時用觸發器更新它。

0

因爲我看不到任何明顯的缺陷與你的MySQL語法,如果你想讓它比快,我會建議去NoSQL的,並使用一個數據庫文件支持Map-Reduce,如HadoopCouchDB。你可以在EC2上的羣集(讀取數百個)機器上承載這個(好吧,我在開玩笑,但是認真你可以在1個機箱上爲每個CPU核心運行1個節點來實現最大速度)。

0

您的查詢將打擊表中的每條記錄,因此您不希望通過首先觸擊索引然後觸擊表來減慢速度,顯然這將導致表中每個記錄有2個IO( 1爲索引,1爲實際表格數據)。

因此,第一個問題變成如何加快全表掃描?

Tune IO。你的磁盤是否快速,碎片整理,不共享(與其他數據,應用程序等),等等。

等等,考慮denormalisation;例如表格上的觸發器,用於統計每個插入,更新和刪除時的適當數據並將其存儲在另一個表中。然後查詢另一個表中的單行數據。

2

使用MySQL Triggers以便將行插入到fileindex中,它執行類似UPDATE meta SET value=value+NEW.size WHERE name='fileindex.count';的操作。

delimiter | 

DROP TRIGGER fileindexafterinsert;| 
CREATE TRIGGER fileindexafterinsert AFTER INSERT ON fileindex 
    FOR EACH ROW BEGIN 
     update meta set value=value+NEW.size where name=CONCAT('fileindex.',NEW.ext); 
    END; 
| 
DROP TRIGGER fileindexafterdelete;| 
CREATE TRIGGER fileindexafterdelete AFTER DELETE ON fileindex 
    FOR EACH ROW BEGIN 
     update meta set value=value-OLD.size where name=CONCAT('fileindex.',OLD.ext); 
    END; 
| 

然後,你只需要做SELECT * FROM meta WHERE name='fileindex.exe' LIMIT 1應該返回小於0.01秒。

0

添加一個覆蓋索引,它基本上包含您在內存中需要的所有列。 我會推薦:alter table fileindex add index covering (ext,TotalSizeGB, size)

應該很好。 (希望)