2016-08-01 28 views
0

這是針對InnoDB的MySQL 5.7。MySQL - 通過分區和索引加載數據

我有一個分區表,我將按分區進行批量數據加載(大量數據)。即我知道我加載的每一批數據都將完全落入一個分區。

現在,用數據加載處理索引的常見方式(據我所知)將首先刪除所有索引,執行數據加載,然後重新創建索引。

但我想知道,因爲我正在通過分區加載,這仍然是最優化的方式(刪除,然後重新創建索引),因爲它似乎我不必要地「觸摸」未更新的分區這條路。

例如

  1. 將數據加載到分區1.
    1. 刪除所有索引 - 什麼也沒有發生,因爲沒有數據。
    2. 加載數據 - 全部進入分區1.
    3. 創建索引 - 只修改parition 1。
  2. 將數據加載到分區2.
    1. 丟棄所有的指標 - 第1分區的所有索引下降(不必要的!)
    2. 加載數據 - 所有進入分區2.
    3. 創建索引 - 分區重新創建1個索引(不必要!)和創建分區2索引。
    4. 因此,加載第二批數據比第一批花費的時間要長得多。而且每個批次都會變得更糟!

在這種情況下,我應該只是預先創建索引和裝載數據的時候放在那裏?

(順便說一句,不用擔心的問題。該數據庫是「離線」,數據加載發生。這樣做的目的僅僅是縮短數據加載的每個批次的時間。)

表架構如下:

CREATE TABLE MYTABLE (
    ID  BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, 
    YEAR SMALLINT UNSIGNED NOT NULL, 
    MONTH TINYINT UNSIGNED NOT NULL, 
    A  CHAR(4), 
    B  VARCHAR(127), 
    C  VARCHAR(15), 
    D  VARCHAR(511), 
    E  TEXT, 
    F  TEXT, 
    G  VARCHAR(127), 
    H  VARCHAR(127), 
    I  VARCHAR(127), 
    J  VARCHAR(511), 
    K  VARCHAR(511), 
    L  BIT(1), 
    CONSTRAINT PKEY PRIMARY KEY (ID, YEAR, MONTH) 
) 
PARTITION BY LIST COLUMNS(YEAR, MONTH) (
    PARTITION PART1 VALUES IN ((2007, 1)), 
    PARTITION PART2 VALUES IN ((2007, 2)), 
    PARTITION PART3 VALUES IN ((2007, 3)), 
    ... 
); 

而且,當然,還有一堆索引(共14個),主要涉及2到4列。 2 TEXT列中沒有任何索引。

+0

InnoDB? SELECTs是什麼樣的?你會添加哪些索引? UTF8?拆分'YEAR'和'MONTH'而不是使用單列'DATE'實際上有益嗎?這些選擇會跨越一個月嗎?你是否總是使用'​​WHERE year = constant AND month = constant'? –

回答

2

如果您使用的是InnoDB,請勿刪除PRIMARY KEY

所有PARTITIONs總是具有相同的索引。所以你不能單獨打開/關閉索引。

請提供SHOW CREATE TABLE作進一步的批評和建議。我可能PARTITIONing是沒用的;有很少的用例值得使用PARTITIONMore info, and use cases

+0

對於這個表格,我有基於時間的數據。每批次都是一個月的數據。分區將有助於數據老化(例如,當一些舊數據不再使用時丟棄整個分區)。 瞭解我無法通過個別分區進行索引。因此,這個問題。每次我加載一批數據時,不是每次刪除和重新創建索引,最好是將索引保留在那裏,以便每當我加載數據時,其他分區都不需要通過刪除和不必要地創建索引來「觸及」? –

+0

哦,我沒有放棄PRIMARY KEY ......只有非PK索引。 –

+0

我明白這個問題,但我沒有直接的答案。無論如何,我希望看到這些索引。那個用例是非常好的。另一個問題:「批次」中有多少行? –