写入与查询

本文介绍AnalyticDB for MySQL中写入与查询的常见问题及解决方法。

说明

当常见问题场景中未明确产品系列时,表明该问题仅适用于AnalyticDB for MySQL数仓版

常见问题概览

企业版、基础版及湖仓版集群是否支持通过JDBC方式查询Hudi表的数据?

支持。在企业版、基础版及湖仓版集群中创建Hudi表后,可直接通过JDBC方式查询Hudi表的数据。

企业版、基础版及湖仓版集群是否支持读取OSS中的Hudi表数据?

支持。通过外表读取OSS中的Hudi表数据的详细信息,请参见通过外表导入湖仓版

企业版、基础版及湖仓版集群是否支持自动切换XIHE MPP作业XIHE BSP作业

提交作业时,手动指定作业提交到Interactive型资源组或Job型资源组,决定了作业是XIHE MPP作业还是XIHE BSP作业。

企业版、基础版及湖仓版集群如何选择XIHE MPP还是XIHE BSP来执行作业?

XIHE BSP默认为异步提交作业,同步提交和异步提交的区别在于客户端是否需要等待查询执行完成。

异步提交会有如下限制:

  • 结果集返回最多10000行。

  • 结果集(包括对应的csv文件下载链接)最多保存30天,最多保存1000个。

建议对执行时间较长、计算量较大,但结果集较小的查询(如INSERT INTO SELECTINSERT OVERWRITE SELECTCREATE TABLE AS SELECT等)使用异步提交。

企业版、基础版及湖仓版集群如何查看XIHE BSP作业的状态?

  • 如果湖仓版集群是通过作业编辑器提交的XIHE BSP作业,可在作业编辑器SQL开发页面下方的执行记录页签查看。

  • 如果湖仓版集群不是通过作业编辑器提交的XIHE BSP作业,可通过系统内部提供的内存表查看。方法如下:

    SELECT status FROM information_schema.kepler_meta_elastic_job_list WHERE process_id='<job_id>';

    查询XIHE BSP作业的状态统计,方法如下。

    SELECT status,count(*) FROM information_schema.kepler_meta_elastic_job_list GROUP BY status;

如何进行资源隔离,减少SQL任务间的相互影响?

数仓版弹性模式集群和企业版、基础版及湖仓版集群支持资源组功能,资源组类型的详细信息请参见数仓版资源组介绍湖仓版资源组介绍。您可以通过创建不同类型的资源组,将SQL作业提交到对应的资源组执行达到资源隔离的效果。

如何处理IN条件过多的问题?

AnalyticDB for MySQL对于IN条件的个数有限制,IN条件个数默认为2000,您也可以根据需求进行调整。

说明

IN条件的个数最大不能超过5000,超过5000会影响性能。

例如将IN条件的个数限制设置为3000,语句如下:

SET ADB_CONFIG max_in_items_count=3000;

如何解决查询数据时提示“Query exceeded maximum time limit of 1800000.00ms”?

AnalyticDB for MySQL对SQL查询执行设置有超时时间,该SQL执行时间超过了默认时间1800000.00ms。您可以为单个查询或全集群所有查询配置查询的超时时间,示例如下:

  • 单个查询生效。

    /*+ QUERY_TIMEOUT=xxx */SELECT count(*) FROM t;
  • 全集群所有查询生效。

    SET ADB_CONFIG QUERY_TIMEOUT=xxx;

    更多信息,请参见常见配置参数

如何解决使用Multi-Statement功能连续执行多个SQL语句时提示“multi-statement be found”?

仅3.1.9.3及以上内核版本的集群支持Multi-Statement功能,您需先查看集群内核版本是否符合要求,若内核版本低于3.1.9.3,请联系技术支持升级版本;若内核版本高于3.1.9.3,但仍有该报错,可能是因为客户端未开启Multi-Statement功能。

例如,使用MySQL JDBC客户端连接集群时,不仅需要执行SET ADB_CONFIG ALLOW_MULTI_QUERIES=true;命令手动开启Multi-Statement功能,还需将JDBC连接属性allowMultiQueries配置为true

如何排查返回结果中的时间被截断的问题?

先通过MySQL客户端进行验证,如果MySQL客户端显示正常,那么需要定位您使用的其他客户端软件对返回结果是否做过特殊处理。

如何解决AES_ENCRYPT内置函数报错?

执行以下语句,出现报错。

 SELECT CONVERT(AES_DECRYPT(AES_ENCRYPT('ABC123','key_string'),'key_string'),char(10));

原因为AES_ENCRYPT(NCRYPT(varbinary x, varchar y)语句中x的数据类型需为varbinary。SQL示例如下。

SELECT CONVERT(AES_DECRYPT(AES_ENCRYPT(CAST('ABC123' AS VARBINARY), 'key_string'), 'key_string'),char(10)); 

为什么会发生查询结果跳变?

在确认数据没有更新的情况下,可能导致查询结果跳变的原因如下:

  • 没有排序的LIMIT。AnalyticDB for MySQL是分布式数据库,查询在多个节点多线程执行,如果某些线程返回了满足LIMIT的行数,查询即终止,所以没有排序的LIMIT的查询结果是一个随机的过程,内部无法保证固定的线程返回结果。

  • 带分组的聚合查询,如果SELECT字段中的某个字段没有聚合函数,也没有出现在GROUP BY字段中,那么这个字段将随机返回一个值。

若仍有问题,请联系技术支持。

为什么单表的排序(ORDER BY)查询耗时长?

原因:数据在存储层没有排序,存储的比较分散,会生成大量的无效数据读取,因此查询耗时会变长。

建议:您可以为进行ORDER BY的字段增加聚集索引(CLUSTERED KEY)。增加聚集索引后,数据会在存储层先完成初步排序,在进行ORDER BY查询时,仅需读取少量数据,进而提升查询性能。增加聚集索引的方法,请参见增加聚集索引

说明
  • 一张表仅支持创建一个聚集索引,若其他字段已经有聚集索引,需先删除,再为ORDER BY的字段增加聚集索引。

  • 大表在增加聚集索引之后,会增加BUILD任务的耗时,进而影响存储节点的CPU使用率。

为什么执行计划里的表扫描行数累加不等于查询的总扫描行数?

一般是由于创建了复制表导致的,复制表在AnalyticDB for MySQL的每个Shard都保存一份数据,当查询复制表时,复制表的查询会在扫描量统计时重复统计。

为什么没有设置主键(primary key)的表,用INSERT OVERWRITE插入,会出现重复数据?

AnalyticDB for MySQL中没有设置主键的表不支持自动去重。

为什么使用查询语句SELECT * FROM TABLE GROUP BY KEY后,报错“Column 'XXX' not in GROUP BY clause

分组查询时不支持使用查询语句SELECT * FROM table GROUP BY key展示查询所有字段,需要显式列出所有字段。SQL示例如下。

SELECT nation.name FROM nation GROUP BY nation.nationkey

查询结果以JSON格式返回时,IN操作符指定值的个数有限制吗?

AnalyticDB for MySQL内核版本为3.1.4及以下版本的集群对IN操作符指定值的个数有限制且个数不能超过16,内核版本为3.1.4以上版本的集群没有限制。查看集群的内核版本的操作步骤,请参见如何查看集群的内核版本?

是否支持OSS上经过GZIP压缩后的CSV文件做为外表数据源?

AnalyticDB for MySQL支持OSS上经过GZIP压缩后的CSV文件做为外表数据源,需要compress_type外表定义加上compress_type=gzip。OSS外表语法,请参见OSS非分区外表

是否支持INSERT ON DUPLICATE KEY?

AnalyticDB for MySQL目前只支持等值更新,不支持算数表达式。

是否支持在UPDATE语句中使用Join?

仅内核版本为3.1.6.4及以上版本的AnalyticDB for MySQL集群支持。详情请参见UPDATE

是否支持在SQL里设置变量?

AnalyticDB for MySQL不支持在SQL里设置变量。

是否支持通过Logstash插件使用INSERT ON DUPLICATE KEY UPDATE语句批量插入数据?

支持。使用INSERT ON DUPLICATE KEY UPDATE语句批量插入数据时,您无需在每个VALUES()语句后都添加ON DUPLICATE KEY UPDATE,仅需在最后一个VALUES()后加上即可。

例如,需要在student_course表中批量插入3条数据时,执行如下语句:

INSERT INTO student_course(`id`, `user_id`, `nc_id`, `nc_user_id`, `nc_commodity_id`, `course_no`, `course_name`, `business_id`)
VALUES(277943, 11056941, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工业会计实战V9.0--77', 'kuaiji'),
(277944, 11056943, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工业会计实战V9.0--88', 'kuaiji'),
(277945, 11056944, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工业会计实战V9.0--99', 'kuaiji')
ON DUPLICATE KEY UPDATE
course_name = '工业会计实战V9.0--77',
business_id = 'kuaiji';

加载内置数据集需要满足什么条件?

集群具有至少24 ACU的存储预留资源,且user_default资源组中至少有16 ACU的计算预留资源。

如何判断内置数据集是否加载成功?

作业开发SQL开发页面可查看加载进度。当加载内置数据集前出现1并为灰质状态,且库表页签下可以查看到ADB_SampleData_TPCH数据库及相关的表,则为加载成功。

加载内置数据集时,提示加载失败或者长时间加载中如何处理?

您需要先通过SQL语句DROP TABLE table_name;删除库中的所有表。表删除以后,再通过SQL语句DROP DATABASE ADB_SampleData_TPCH;删除内置数据集的库。删除ADB_SampleData_TPCH数据库后,重新加载数据集。

数据库普通账号如何使用内置数据集?

内置数据集功能遵循AnalyticDB for MySQL的权限管理规则,即使集群已加载内置数据集,数据库普通账号没有ADB_SampleData_TPCH数据库的权限也无法使用,需要高权限账号为普通账号授权。授权语句为:

GRANT select ON ADB_SampleData_TPCH.* TO <user_name>;

内置数据集加载完成后,如何进行测试?

数据集加载成功后,AnalyticDB for MySQL默认提供对应的查询脚本,您可以在SQL开发页面的脚本页签执行示例查询语句。查询语句的详情,请参见TPC-H测试集

重要

为保证数据集的完整性,建议仅对ADB_SampleData_TPCH数据库执行查询操作。若由于DDL或DML变更导致数据集加载状态异常,请尝试删除ADB_SampleData_TPCH数据库并重试加载数据集。