本文介紹了掃描全部/部分分庫分表的HINT語法和示例。

除了可以將SQL單獨(dú)下發(fā)到一個(gè)或多個(gè)分庫執(zhí)行,PolarDB-X還提供了掃描全部/部分分庫與分表的SCAN HINT。使用SCAN HINT,您可以一次將SQL下發(fā)到每一個(gè)分庫執(zhí)行, 比如查看某個(gè)分庫上的所有分表,或者查看某個(gè)邏輯表的每張物理表中的數(shù)據(jù)量等。

通過SCAN HINT,可以指定四種執(zhí)行SQL的方式:
  1. 在所有分庫的所有分表上執(zhí)行;
  2. 在指定分庫的所有分表上執(zhí)行;
  3. 在指定分庫分表上執(zhí)行,根據(jù)條件計(jì)算物理表名稱;
  4. 在指定分庫分表上執(zhí)行,顯式指定物理表名;

SCAN HINT支持 DML、DDL和部分DAL語句。

語法

# SCAN HINT

# 將SQL語句下發(fā)到所有分庫的所有分表上執(zhí)行
SCAN()                               

# 將SQL語句下發(fā)到指定分庫的所有分表上執(zhí)行
SCAN(NODE="node_list")               # 指定分庫

# 將SQL語句下發(fā)到指定分庫分表上執(zhí)行,根據(jù)條件計(jì)算物理表名稱
SCAN(
  [TABLE=]"table_name_list"          # 邏輯表名
  , CONDITION="condition_string"     # 使用TABLE和CONDITION中的內(nèi)容計(jì)算物理庫表名稱
  [, NODE="node_list"] )             # 過濾通過CONDITION計(jì)算出的結(jié)果,僅保留指定物理庫

# 將SQL語句下發(fā)到指定分庫分表上執(zhí)行,顯式指定物理表名
SCAN(
  [TABLE=]"table_name_list"          # 邏輯表名
  , REAL_TABLE=("table_name_list")   # 物理表名,對(duì)所有物理庫使用相同的物理表名
  [, NODE="node_list"] )             # 過濾通過CONDITION計(jì)算出的結(jié)果,僅保留指定物理庫


# 物理/邏輯表名列表
table_name_list: 
    table_name [, table_name]...

# 物理庫列表,支持GROUP_KEY和GROUP的序號(hào), 可以通過`SHOW NODE`語句獲得 
node_list: 
    {group_key | group_index} [, {group_key | group_index}]...
    
# 支持SQL WHERE的語法,需要為每一張表設(shè)置條件,如:t1.id = 2 and t2.id = 2
condition_string: 
    where_condition

            

注意事項(xiàng)

  • PolarDB-X自定義HINT支持/*+TDDL:hint_command*//!+TDDL:hint_command*/兩種格式。
  • 如果使用/*+TDDL:hint_command*/格式,在使用MySQL官方命令行客戶端執(zhí)行帶有PolarDB-X自定義HINT的SQL時(shí),請(qǐng)?jiān)诘卿浢钪屑由?code class="ph codeph" id="codeph-iil-0se-sai">-c 參數(shù)。否則,由于PolarDB-X自定義HINT是以 MySQL 注釋形式使用的,該客戶端會(huì)將注釋語句刪除后再發(fā)送到服務(wù)端執(zhí)行,導(dǎo)致PolarDB-X自定義HINT失效。具體請(qǐng)查看MySQL 官方客戶端命令

示例

  • 在所有分庫的所有分表上執(zhí)行:
    SELECT /*+TDDL:scan()*/ COUNT(1) FROM t1      

    執(zhí)行后會(huì)下發(fā)SQL語句到t1的所有物理表上執(zhí)行,并將結(jié)果集合并后返回。

  • 在指定分庫的所有分表上執(zhí)行:
    SELECT /*+TDDL:scan(node='0,1,2')*/ COUNT(1) FROM t1          

    執(zhí)行后會(huì)首先計(jì)算出t1在0000, 0001, 0002分庫上的所有物理表,然后下發(fā)SQL語句并將結(jié)果集合并后返回。

  • 按條件在指定分表上執(zhí)行:
    SELECT /*+TDDL:scan('t1', condition='t1.id = 2')*/ COUNT(1) FROM t1           

    執(zhí)行后會(huì)首先計(jì)算出邏輯表t1滿足condition條件的所有物理表,然后下發(fā)SQL語句并將結(jié)果集合并后返回。

  • 按條件在指定分表上執(zhí)行,有JOIN的情況:
    SELECT /*+TDDL:scan('t1, t2', condition='t1.id = 2 and t2.id = 2')*/ * FROM t1 a JOIN t2 b ON a.id = b.id WHERE b.name = "test"
                

    執(zhí)行后會(huì)首先計(jì)算出邏輯表t1t2滿足 condition 條件的所有物理表,然后下發(fā) SQL 語句并將結(jié)果集合并后返回。 注意:使用該自定義注釋需要保證兩張表的分庫和分表數(shù)量一致,否則PolarDB-X計(jì)算出的兩個(gè)鍵值對(duì)應(yīng)的分庫不一致,就會(huì)報(bào)錯(cuò)。

  • 在指定分庫分表上執(zhí)行,顯式指定物理表名:
    SELECT /*+TDDL:scan('t1', real_table=("t1_00", "t1_01"))*/ COUNT(1) FROM t1
                

    執(zhí)行后會(huì)下發(fā)SQL語句到所有分庫的t1_00``t1_01分表上,合并結(jié)果集后返回。

  • 在指定分庫分表上執(zhí)行,顯式指定物理表名, 有JOIN的情況:
    SELECT /*+TDDL:scan('t1, t2', real_table=("t1_00,t2_00", "t1_01,t2_01"))*/ * FROM t1 a JOIN t2 b ON a.id = b.id WHERE b.name = "test";
                

    執(zhí)行后會(huì)下發(fā)SQL語句到所有分庫的t1_00t2_00t1_01t2_01分表上,合并結(jié)果集后返回。