日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

文檔

多元索引最佳實踐

更新時間:

本文從數據表設計、多元索引設計、多元索引使用三個方面介紹了使用多元索引的最佳實踐。

數據表相關設計實踐

主鍵設計

Tablestore數據表根據分區鍵進行Range范圍分區,主鍵的設計會影響多元索引的同步速度和部分場景下的查詢水平拓展。

  • 主鍵需要盡可能的離散,例如使用MD5進行哈希處理。常見的反例包括使用自增ID、當前時間戳作為分區鍵。關于主鍵設計的更多信息,請參見表設計

  • 如果需要在數據表上根據主鍵前綴進行批量數據的拉取,則可以進行一些特殊的主鍵設計,然后查詢數據時直接在數據表上進行GetRange操作來快速拉取數據。具體操作,請參見讀取數據

  • 如果要經常使用多元索引TermQuery查詢某一字段的值,例如淘寶App中每個查詢條件中均會包括指定UserId,則推薦將UserId設置為主鍵,具體優化操作請參見“索引路由優化”內容。

主鍵設計對多元索引的同步速度有一定的影響,對數據表主鍵的要求是寫入數據時要盡可能分散到數據表的不同分區,因此如果寫入TPS較高時,需要盡可能分散在數據表的多個分區中,避免出現寫單分區、寫尾部分區等問題。目前僅支持從數據表中異步寫入數據到多元索引中。

在訂單場景中,當用戶拼接“UserId+商品ID”作為分區鍵且商品ID是自增的時,如果某個UserId的寫TPS過高,則會發生寫尾部分區問題,即寫入的均為Tablestore數據表的最后一個分區,這樣寫入數據會影響多元索引的同步延時和查詢性能。在此場景中可以將“商品ID”進度MD5處理,分區鍵設置的建議如下:

  • 如果無需在數據表上根據UserId進行范圍查詢,則建議直接使用“商品ID”進行MD5后處理的值作為分區鍵。

  • 如果要在數據表上根據UserId進行范圍查詢,則建議拼接“UserId”和“商品ID”進行MD5后處理的值作為分區鍵。

貨幣、價格的數據存儲類型

Tablestore只支持Double類型,不支持BigDecimal類型。當實際業務中涉及到金額等要求非常精確的字段時,推薦使用Long類型進行存儲,例如5元3角2分存儲為53200。

分表存儲

目前推薦一個多元索引的數據在200億行以內。如果數據規模超過200億行,請聯系表格存儲技術支持進行評估和設計。例如某用戶最大的log表當前為61億行,一年增長21億行,3~5年內不會超過200億行,因此可以不用分表存儲。

當存量數據較大且增長很快時,可以使用分表存儲,請聯系表格存儲技術支持進行分表評估和設計。

大批量導入數據前準備

首次創建Tablestore的數據表后,在導入數據前,如果數據較多,例如超過10億行,請聯系表格存儲技術支持進行數據表的預分區,使數據導入速度更快。

數據量較大的情況下,推薦先將數據導入到數據表再創建多元索引,有利于提升存量數據的索引構建速度。

多元索引相關設計實踐

索引字段類型規劃

在多元索引中,不同類型字段的索引物理結構設計不同。請在數據表中寫入數據時提前規劃合適的字段類型。

  • Keyword字段類型底層實現使用FST(Finite State Transducers)算法+倒排鏈,因此使用Keyword字段類型進行精確查詢(TermQuery)時速度快。

  • Long字段類型底層實現使用BKD-tree,因此使用Long字段類型進行范圍查詢(RangeQuery)時速度快。

常見索引字段類型設計示例如下:

  • Type、Status等枚舉類型字段的取值為0、1、2三種,雖然字段取值為數字,但是通過在數據表中保存為字符串類型并在創建多元索引時索引為Keyword類型,您可以使用TermQuery或者多詞精確查詢(TermsQuery)(類似SQL中的in操作)對枚舉類型字段進行快速查詢。

  • UserId字段的取值為一個長整型數字,實際業務中通常使用UserId進行TermQuery,因此UserId需要在數據表中保存為字符串類型。

  • isDeleted等狀態字段的取值可能為0或者1,因此需要在數據表中保存為字符串類型或者布爾類型。

如果實際業務中已使用了不合適的字段類型且不方便修改存量業務的數據類型,您可以使用虛擬列動態修改schema功能進行字段類型調整以達到加速查詢的目的。其中動態修改schema功能用于實現對原有業務的平滑升級,虛擬列用于實現字段類型的調整。

索引預排序

使用多元索引查詢數據時,如果大多數查詢均按照某個模式進行排序時,則可以通過設置預排序來節省一些排序時間。

當命中的數據越多時,使用預排序帶來的性能優化效果越好。默認情況下,多元索引按照數據表的所有主鍵進行預排序。目前該功能僅支持使用SDK創建預排序。具體操作,請參見創建多元索引

索引路由優化

使用多元索引查詢數據時,如果均會帶有某個字段時,例如淘寶App中每個查詢均會帶有UserId,則推薦使用索引路由優化。

多元索引的數據分布默認情況下是根據數據表的所有主鍵進行Hash分區,因此使用多元索引查詢數據時會訪問索引引擎的所有分區。如果為多元索引配置路由后,則可以改變數據分布,根據路由鍵(而不是之前的所有主鍵)將數據進行Hash分區,一個確定的路由鍵會落在明確的一個或多個分區上。使用路由鍵的好處如下:

  • 顯著減少長尾查詢:未使用路由鍵前,每個查詢均會訪問索引引擎的每個分區,整體查詢延時取決于最慢的分區,因此如果有一個分區有毛刺或者網絡卡頓,則會造成整體查詢請求變慢。

  • 支持更高的QPS查詢能力:帶有路由的請求僅訪問索引引擎的部分分區,因此不會有讀放大,對集群的資源消耗較少,可以支持更高的QPS。

  • 如果多元索引的路由鍵設計合理,則多元索引的規模無上限。

關于使用路由鍵的具體操作,請參見多元索引路由字段的使用

使用路由鍵的常見問題如下:

  • 一般情況下,推薦路由鍵的值要盡量多樣,同一個路由鍵下的總數據量不要太多(例如不要超過1億行)。如果一個路由鍵下的數據太多,則建議將多個不變的字段拼接為路由鍵。

  • 如果用戶設置UserId為路由鍵,但是遇到了Query中不指定UserId的場景,則查詢數據時會訪問引擎中的所有分區,不影響查詢結果的完整性。

  • 如果用戶查詢QPS不高或者數據量小于2億行,則無需使用索引路由優化。

邏輯字段和物理字段映射

當要使用的索引字段個數超過多元索引支持的最大索引字段個數時,您可以通過“邏輯字段和物理字段映射”方式使所有用戶共享多元索引的一些字段。假設系統中有1000個用戶,每個用戶擁有個性化的列名,且需要使用多元索引的10個字段。具體設計步驟如下:

  1. 索引設計。

    假設用戶只需要使用Keyword和Long數據類型。創建一個多元索引,該多元索引包含200個字段(不同類型的字段數量請根據業務需要進行個性化設置)和其它業務必要的非個性化字段。多元索引中固定的字段名如下:

    • keyword_1,keyword_2,....,keyword_100

    • long_1,long_2,...,long_100

    • 其它業務必要的非個性化字段

  2. 準備一個meta映射表。如果meta映射表數據量不大,建議緩存到內容中。

    meta映射表中字段與已創建的多元索引字段的關系如下:

    • “用戶1”有Keyword類型字段a、b、c,在meta映射表中對“用戶1”記錄一行數據,其中字段a映射為索引keyword_1、字段b映射為索引keyword_2、字段c映射為索引keyword_3,有Long類型字段依次類推。

    • “用戶2”有Keyword類型字段b、c、d,在meta映射表中對“用戶2”記錄一行數據,其中字段b映射為索引keyword_1、字段c映射為索引keyword_2、字段d映射為索引keyword_3,有Long類型字段依次類推。

  3. 根據meta映射表的映射進行數據寫入與查詢。

    • 數據寫入:根據meta映射表,將物理字段寫入到邏輯列中。

    • 數據查詢:根據meta映射表將用戶查詢字段進行轉化,例如“用戶2”要查詢b=4&&d=5,則轉化為keyword_1=4&&keyword_3=5。

多元索引使用實踐

查詢優化

如果查詢Query特別復雜,例如條件過多、嵌套太深、TermsQuery中的元素過多等,則查詢延時可能會較高,因此推薦用戶精簡Query,只保留必要的條件。

目前服務端會自動進行查詢改寫和查詢優化,一般情況下無需關注。如果出現查詢延時高的情況,請聯系表格存儲技術支持進行查詢優化。

全文索引

匹配查詢(MatchQuery)和短語匹配查詢(MatchPhraseQuery)主要用于分詞Text類型字段的全文索引場景。

在Keyword類型字段上,MatchQuery和TermQuery可能查詢結果一致,但是MatchQuery會有額外的分詞處理流程,性能相對較差,因此不建議在Keyword類型字段上誤用MatchQuery。

模糊查詢

對于通配符查詢(WildcardQuery)中查詢模式為*word*的場景,即“任意子串”查詢需求,您可以使用模糊分詞方式(模糊分詞和短語匹配查詢MatchPhraseQuery組合使用)來實現性能更好的模糊查詢。具體操作,請參見模糊查詢

翻頁和Token編碼

推薦使用Token翻頁方式進行深度翻頁。當要對Token(類型為byte[])進行持久化存儲時,您可以使用Base64編碼將Token編碼為字符串后再進行存儲。如果直接進行字符串編碼,例如new String(token) ,則會造成token內容丟失。

關于Token翻頁方式的更多信息,請參見排序和翻頁