2013-08-27 72 views
1

我有一個帖子表,列id (INT, primary key), name(VARCHAR), status(TINYINT)。該職位的狀態可以是1, 2, 3 or 4。比方說,我想選擇狀態爲2的帖子。我如何優化表以獲得快速查詢,因爲爲狀態字段添加索引不會有太大的幫助。tinyint列優化mysql

我使用mysql 5.5。引擎可以是innodbmyisam

感謝

更新評論

據我瞭解指數是如何工作的,是當我們添加索引它有點創建列,但在一個有序的方式複製 - 數字(或文本 - 按字母順序),所以它提供了二進制搜索的可能性。所以,如果我們需要找到某個值,我們可以避免對錶格進行全面掃描。但在這種情況下,假設我的表格中有100K行,並且有大致的說法 - 等於行數1, 2, 3 and 4。如果我爲該字段添加索引,畢竟它應該對剩餘的25k行進行線性搜索,並且如果我們考慮到添加索引會降低插入和更新速度,可能不值得。

查詢 - SELECT id, name FROM posts WHERE status = 2

+3

爲什麼不爲狀態字段添加索引幫助那麼大? – bumperbox

+0

爲什麼添加索引不會加快查詢速度?你在做什麼類型的查詢?請舉個例子。 – Ander2

+1

分成4個表格! –

回答

2

如何以及索引工作在這種情況下取​​決於兩個因素。這裏有三種情況,索引可以很好地工作(第三次感謝Vatev)。

第一個是當狀態2的記錄很少的時候。比如說,你有一個有100萬條記錄的表,並且在任何給定的時間只有100個記錄具有狀態2。索引將幫助您找到它們。

第二種情況是status是表上的主鍵(或者至少是主鍵中的第一列)。這將任何表掃描限制爲status = 2僅限於表的一部分。當然,擁有狀態主鍵會使狀態的後續更新更加昂貴,因爲必須根據狀態值重新定位數據。

第三種情況是當status - 或索引中包含status - 的列是覆蓋索引時。這意味着查詢所需的所有列都位於索引中,因此引擎不必查找原始數據頁面。

一般來說,我建議對低基數字段的索引。這是一條通用規則,但有些情況下這樣的指數可以提高業績。

+0

第二種情況也適用於使用以狀態開頭的覆蓋索引的查詢。 – Vatev

+0

@Vatev。 。 。優秀點。我修改了答案以包含這一點。 –

+0

@戈登林諾夫,我更新了這個問題。謝謝 – dav

2

我不知道你的應用程序或SQL要求

你可以分批不使用限制,因爲沒有有效的桌子上數以百萬計關記錄,因爲它會創建一個(硬盤/內存)的臨時接他們表如果你這樣查詢。

SELECT id, name FROM posts WHERE status = 2 LIMIT 1000000, 1000000 

如果您解釋一下上面的查詢你西港島線看到它會掃描200萬行,將使用(硬盤/內存)臨時表中,最糟糕的情況下,它需要一個基於磁盤如果內存已滿

更好的辦法是使用基於你的狀態的位置(確保指數)

SELECT id, name FROM posts WHERE status = 2 and position >= 1 and <= 1000000 
SELECT id, name FROM posts WHERE status = 2 and position >= 1000001 and <= 2000000 
... 
... 

真正的低基數的域真的不應該索引的更好的辦法是,也許你可以用LIST分區,以獲得更多的測試性能,但它仍然需要一個完整的「表(分區)「掃描

查看http://sqlfiddle.com/#!2/d947c/7查看示例並查看EXPLAIN PARTITIONS語句以查看WHERE狀態= 1時將只使用partition_post_status_id_1。

或者看到覆蓋索引方法http://sqlfiddle.com/#!2/20b0d/1與分區

而且querys涉及聚合函數,如SUM()和COUNT()可以運行並行化的劃分,以獲得更高的性能自動

0

如果你的要求是真的經常會遇到這種類型的查詢,並獲取整個表的1/4,我建議你換表使用InnoDB引擎和主鍵(status, id)

CREATE TABLE posts 
(id INT, 
    name VARCHAR (whatever), 
    status TINYINT, 
    PRIMARY KEY (status, id), 
    UNIQUE INDEX (id) 
) ENGINE = InnoDB ; 

這樣,您仍然擁有(id)唯一的聚簇索引(InnoDB默認選擇爲主鍵)首先基於status,因此您想要的數據將以WHERE status = @X的順序存儲在磁盤上。