全部产品
云市场

扫描全部/部分分库分表

更新时间:2018-12-21 10:38:04

本文适用于 DRDS 5.3 及以上版本,其他版本请参考DRDS 5.2 HINT 文档

除了可以将 SQL 单独下发到一个或多个分库执行,DRDS 还提供了扫描全部/部分分库与分表的SCAN HINT。使用SCAN HINT,您可以一次将 SQL 下发到每一个分库执行, 比如查看某个分库上的所有分表,或者查看某个逻辑表的每张物理表中的数据量等。

通过SCAN HINT,可以指定四种执行 SQL 的方式:

  1. 在所有分库的所有分表上执行
  2. 在指定分库的所有分表上执行
  3. 在指定分库分表上执行,根据条件计算物理表名称
  4. 在指定分库分表上执行,显式指定物理表名

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

注意:

  • DRDS 自定义 HINT 支持 /*+TDDL:hint_command*//!+TDDL:hint_command*/ 两种格式。

  • 如果使用 /*+TDDL:hint_command*/ 格式,在使用 MySQL 官方命令行客户端执行带有 DRDS 自定义 HINT 的 SQL 时,请在登录命令中加上 -c 参数。否则,由于 DRDS 自定义 HINT 是以 MySQL 注释 形式使用的,该客户端会将注释语句删除后再发送到服务端执行,导致 DRDS 自定义 HINT 失效。具体请查看 MySQL 官方客户端命令

语法

  1. # SCAN HINT
  2. # 将 SQL 语句下发到所有分库的所有分表上执行
  3. SCAN()
  4. # 将 SQL 语句下发到指定分库的所有分表上执行
  5. SCAN(NODE="node_list") # 指定分库
  6. # 将 SQL 语句下发到指定分库分表上执行,根据条件计算物理表名称
  7. SCAN(
  8. [TABLE=]"table_name_list" # 逻辑表名
  9. , CONDITION="condition_string" # 使用 TABLE 和 CONDITION 中的内容计算物理库表名称
  10. [, NODE="node_list"] ) # 过滤通过 CONDITION 计算出的结果,仅保留指定物理库
  11. # 将 SQL 语句下发到指定分库分表上执行,显式指定物理表名
  12. SCAN(
  13. [TABLE=]"table_name_list" # 逻辑表名
  14. , REAL_TABLE=("table_name_list") # 物理表名,对所有物理库使用相同的物理表名
  15. [, NODE="node_list"] ) # 过滤通过 CONDITION 计算出的结果,仅保留指定物理库
  16. # 物理/逻辑表名列表
  17. table_name_list:
  18. table_name [, table_name]...
  19. # 物理库列表,支持 GROUP_KEY 和 GROUP 的序号, 可以通过 `SHOW NODE` 语句获得
  20. node_list:
  21. {group_key | group_index} [, {group_key | group_index}]...
  22. # 支持 SQL WHERE 的语法,需要为每一张表设置条件,如:t1.id = 2 and t2.id = 2
  23. condition_string:
  24. where_condition

示例

  • 在所有分库的所有分表上执行

    1. SELECT /*+TDDL:scan()*/ COUNT(1) FROM t1

    执行后会下发 SQL 语句到t1的所有物理表上执行,并将结果集合并后返回

  • 在指定分库的所有分表上执行

    1. SELECT /*+TDDL:scan(node='0,1,2')*/ COUNT(1) FROM t1

    执行后会首先计算出t1在 0000, 0001, 0002 分库上的所有物理表,然后下发 SQL 语句并将结果集合并后返回。

  • 按条件在指定分表上执行

    1. SELECT /*+TDDL:scan('t1', condition='t1.id = 2')*/ COUNT(1) FROM t1

    执行后会首先计算出逻辑表t1满足 condition 条件的所有物理表,然后下发 SQL 语句并将结果集合并后返回。

  • 按条件在指定分表上执行,有 JOIN 的情况

    1. 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"

    执行后会首先计算出逻辑表t1 t2满足 condition 条件的所有物理表,然后下发 SQL 语句并将结果集合并后返回。注意:使用该自定义注释需要保证两张表的分库和分表数量一致,否则 DRDS 计算出的两个键值对应的分库不一致,就会报错。

  • 在指定分库分表上执行,显式指定物理表名

    1. SELECT /*+TDDL:scan('t1', real_table=("t1_00", "t1_01"))*/ COUNT(1) FROM t1

    执行后会下发 SQL 语句到所有分库的t1_00``t1_01分表上,合并结果集后返回。

  • 在指定分库分表上执行,显式指定物理表名, 有 JOIN 的情况

    1. 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";

    执行后会下发 SQL 语句到所有分库的t1_00 t2_00 t1_01 t2_01分表上,合并结果集后返回。