2013-03-26 69 views
3

我有一個表game_log與字段id,game_id和幾個varchar字段。如何分區與兩個索引的MySQL表

id是主鍵和game_id是非唯一的密鑰。

這裏有兩種常用的查詢:

SELECT * FROM game_log ORDER BY id DESC LIMIT 20 
SELECT * FROM game_log WHERE game_id = <value> ORDER BY id DESC 

表是巨大的(6.1GB和32M行)。 InnoDB的。其中的行隨機添加(每個查詢一個)。另外,一些遊戲正在被刪除。

我需要減少磁盤IO和imrpove響應。

我應該使用keyrange分區?如果range,那麼通過id或通過game_id?有沒有理論?

+0

使用分區,確保每個分區'innodb_buffer_pool_size'內配合,以避免I/O分頁 – 2013-03-26 04:04:03

回答

4

按範圍使用分區。

如果通過鍵分區,無論你的例子查詢需要接觸每個分區。

的理論是,通過KEY分區是由像散列分區,在主鍵的該連續值綁定到被存儲在單獨的分區。通過查詢一系列id值,可以破壞分區修剪。

演示:

CREATE TABLE `game_log` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `game_id` int(11) NOT NULL DEFAULT '0', 
    `xyz` varchar(15) DEFAULT NULL, 
    PRIMARY KEY (`id`,`game_id`) 
) 
PARTITION BY KEY() 
PARTITIONS 13; 

INSERT INTO game_log (game_id) VALUES (1), (2), (3), (4), (5), (6); 

EXPLAIN PARTITIONS SELECT * FROM game_log ORDER BY id DESC LIMIT 3\G 
      id: 1 
    select_type: SIMPLE 
     table: game_log 
    partitions: p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 

EXPLAIN PARTITIONS SELECT * FROM game_log WHERE game_id = 4 ORDER BY id DESC LIMIT 3\G 
      id: 1 
    select_type: SIMPLE 
     table: game_log 
    partitions: p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 

如果您在game_id通過分區範圍然而,你可以得到分區修剪當你查詢特定game_id至少幫助你。但是,通過id desc查詢任何game_id順序仍然必然會觸及每個分區。

CREATE TABLE `game_log` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `game_id` int(11) NOT NULL DEFAULT '0', 
    `xyz` varchar(15) DEFAULT NULL, 
    PRIMARY KEY (`id`,`game_id`) 
) 
PARTITION BY RANGE (game_id) 
(PARTITION p1 VALUES LESS THAN (3), 
PARTITION p2 VALUES LESS THAN (6), 
PARTITION p3 VALUES LESS THAN MAXVALUE); 

INSERT INTO game_log (game_id) VALUES (1), (2), (3), (4), (5), (6); 

EXPLAIN PARTITIONS SELECT * FROM game_log ORDER BY id DESC LIMIT 3\G 
      id: 1 
    select_type: SIMPLE 
     table: game_log 
    partitions: p1,p2,p3 

EXPLAIN PARTITIONS SELECT * FROM game_log WHERE game_id = 4 ORDER BY id DESC LIMIT 3\G 
      id: 1 
    select_type: SIMPLE 
     table: game_log 
    partitions: p2 
+0

非常感謝。我想我也可以在「id DESC LIMIT」查詢中添加'game_id> [來自最後一個分區的某個遊戲ID]'。 – 2013-03-26 04:58:45

+0

嗯,這對我來說很奇怪:'PRIMARY KEY(id,game_id)',需要時。我還需要一個單獨的''game_id'的非唯一鍵嗎? – 2013-03-26 05:21:35

+1

是的,在game_id上​​有一個單獨的索引會很有幫助。嘗試使用EXPLAIN分析查詢,如前所示,在game_id上​​創建額外索引之前和之後,您會看到它使用索引。 (使用測試數據庫執行此操作,而不是使用6 GB生產系統。) – 2013-03-26 12:45:03