2016-07-19 27 views
1
  1. 我在MySQL 5.7上使用InnoDB引擎。MySQL - 使用密鑰分區時將數據分佈不均勻分區

  2. 我有一張表格,其中一列是一個(非唯一的)三字母國家代碼(例如,新加坡的「SGP」,日本的「JPN」等)。

  3. 對於大多數我的查詢,這個國家代碼列是第一WHERE子句我通過(例如WHERE COUNTRY_CODE = 'SGP')濾波器

  4. 因此,我想(子)分區表通過此列。由於我的大部分查詢都將使用一個國家/地區代碼,因此他們只會以這種方式觸及一個分區。

  5. 但是,由於大量不同的國家代碼,我不想使用LIST分區,我必須明確地滿足每個國家/地區的代碼。

  6. 所以我用KEY分區,8分區。我認爲密鑰分區(即哈希值)會給我一個或多或少的8個分區的均勻分配(不一定非常完美)。

  7. 但是,我所經歷的是,在8個分區中,其中4個是完全不變的。

這是我的CREATE TABLE語句的抽象:

CREATE TABLE TBL_EATING_PLACES (
    ID INT UNSIGNED AUTO_INCREMENT NOT NULL, 
    TYPE_OF_FOOD SMALLINT UNSIGNED NOT NULL, 
    SUBTYPE_OF_FOOD SMALLINT UNSIGNED NOT NULL, 
    COUNTRY_CODE CHAR(3) NOT NULL, 
    ADDRESS VARCHAR(255), 
    ... 
    OTHER_NON_RELEVANT_COLUMNS ..., 
    ..., 
    CONSTRAINT PKEY PRIMARY KEY (ID, TYPE_OF_FOOD, SUBTYPE_OF_FOOD, COUNTRY_CODE) 
) 
ENGINE = InnoDB 
PARTITION BY LIST COLUMNS(TYPE_OF_FOOD, SUBTYPE_OF_FOOD) SUBPARTITION BY KEY(COUNTRY_CODE) SUBPARTITIONS 8 (
    PARTITION P_1_1 VALUES IN ((1, 1)), 
    PARTITION P_1_2 VALUES IN ((1, 2)), 
    PARTITION P_2_1 VALUES IN ((2, 1)), 
    PARTITION P_1_2 VALUES IN ((2, 2)), 
    PARTITION P_1_3 VALUES IN ((2, 2)), 
); 

這有什麼錯我是如何做的KEY分區,使得其結果只擊中分區的一半?

+0

但它真的這樣工作嗎?如果我已經正確理解你的分區,你實際上需要閱讀多個分區,你可以通過國家代碼進行查詢(因爲表格首先被TYPE_OF_FOOD,SUBTYPE_OF_FOOD分區) – e4c5

+0

是的,對不起,我簡化了並放大了問題。我的所有查詢都將首先按TYPE_OF_FOOD和SUBTYPE_OF_FOOD進行過濾(這是隱式的,前端用戶甚至不會選擇)。 然後,可以選擇按照COUNTRY_CODE進行過濾,對於我的大部分用途,我通常會這樣做。 我沒有詳細說明(主要)分區,因爲我觀察到運行良好(即數據進入正確的分區)。 –

+0

只是一個想法,我不知道MySQL如何做散列,並且不確定它是否相關......但是「詞彙親密度」影響兩個值是否散列到同一分區? (例如瑞士(CHE)和中國(CHN),澳大利亞(AUS)和奧地利(AUT)),無論如何,有什麼辦法可以查看哪些行位於哪些分區? –

回答

1

密鑰分區有什麼問題?它提供零利益。不要使用它。相反,請提供合適的複合與您的查詢匹配的索引。

(添加到解決問題的意見......)

通常是一個綜合指數可以做什麼呢劃分等價。 「分區鍵」進行「分區修剪」來選擇一個(或幾個)分區來查看。通過將「分區鍵」作爲索引中的第一列,您可以獲得相同的效果。 (是的,也有例外。)

分區有一些開銷。每個分區都是一個文件;打開文件是昂貴的。在某些情況下,所有分區在修剪之前都會打開。它曾經是INSERT上沒有修剪。 (Yuck!)(其中一些問題已在新版本中解決,但仍有一些開銷。)

我已經看過很多子分區和非RANGE分區的例子。我只看到了4種索引不會像分區那樣「好」的情況。我假設你發現我的博客列出了4個。這裏有一個副本:Partition Maintenance

二維搜索需要「減少搜索空間」。這是4種情況之一。 RANGE分區處理一個維度,PRIMARY KEY處理另一個維度。這有效地工作(但與凌亂的代碼)至Find the 10 nearest pizza parlors

BY RANGE是唯一可以處理值範圍(如日期範圍)的分區。HASH將簡單搜索全部的分區。

BY LIST 可能與BY RANGE一樣好,但只適用於確切的值。然後我回過頭來說「爲什麼不把分區鍵放在任何其他索引的前面」!

如果有人能找到第五個用例,我不能提供沒有分區的等效性能,我會很高興地增加我的博客。

+0

Hi @ rick-james,當我在Google上搜索這個問題時,發現了你的博客,我必須說你的文章非常有啓發性!有幾點我不明白,但(不知道你是否可以在這裏解釋)。 (a)爲什麼分區對性能通常沒有用處?直觀地說,如果它減少了搜索空間,它應該至少與索引一樣有效,不是? (b)爲什麼子分區無用(進一步縮小了搜索空間,不是?)(c)與RANGE相比,爲什麼KEY或HASH分區無用? (d)LIST分區如何(看起來與RANGE相同)? –

+0

我增加了我的答案。也許我涵蓋了你所有的問題? –

+0

感謝里克詹姆斯的解釋!我很驚訝,(a)所有分區在修剪前都會被打開(噢,爲什麼?),(b)使用HASH(我想也是KEY)分區,所有分區都被搜索(然後做什麼操作散列?) –