-
3.最后一步是测试和验证日志表是否正确。以下是添加触发器后对表进行更新的测试:12345678UPDATE Orders SET InternalComments = 'Item is no longer backordered', BackorderOrderID = NULL, IsUndersupplyBackordered = 0, LastEditedBy = 1, LastEditedWhen = SYSUTCDATETIME()FROM sales.OrdersWHERE Orders.OrderID = 10;结果如下:点击并拖拽以移动上面省略了一些列,但是我们可以快速确认已经触发了更改,包括日志表末尾新增的列。INSERT和DELETE前面的示例中,进行插入和删除操作后,读取日志表中使用的数据。这种特殊的表可以作为任何相关写操作的一部分。INSERT将包含**入操作触发,DELETE将被删除操作触发,UPDATE包含**入和删除操作触发。对于INSERT和UPDATE,将包含表中每个列新值的快照。对于DELETE和UPDATE操作,将包含写操作之前表中每个列旧值的快照。触发器什么时候最有用DML触发器的最佳使用是简短、简单且易于维护的写操作,这些操作在很大程度上独立于应用程序业务逻辑。触发器的一些重要用途包括:记录对历史表的更改审计用户及其对敏感表的操作。向表中添加应用程序可能无法使用的额外值(由于安全限制或其他限制),例如: 登录/用户名 操作发生时间服务器/数据库名称简单的验证。关键是让触发器代码保持足够的紧凑,从而便于维护。当触发器增长到成千上万行时,它们就成了开发人员不敢去打扰的黑盒。结果,更多的代码被添加进来,但是旧的代码很少被检查。即使有了文档,这也很难维护。为了让触发器有效地发挥作用,应该将它们编写为基于设置的。如果存储过程必须在触发器中使用,则确保它们在需要时使用表值参数,以便可以基于集的方式移动数据。下面是一个触发器的示例,该触发器遍历id,以便使用结果顺序id执行示例存储过程:123456789101112131415161718CREATE TRIGGER TR_Sales_Orders_Process ON Sales.Orders AFTER INSERTASBEGIN SET NOCOUNT ON; DECLARE @count INT; SELECT @count = COUNT(*) FROM inserted; DECLARE @min_id INT; SELECT @min_id = MIN(OrderID) FROM inserted; DECLARE @current_id INT = @min_id; WHILE @current_id < @current_id + @count BEGIN EXEC dbo.process_order_fulfillment @OrderID = @current_id; SELECT @current_id = @current_id + 1; ENDEND虽然相对简单,但当一次插入多行时对 Sales.Orders的INSERT操作的性能将受到影响,因为SQL Server在执行process_order_fulfillment存储过程时将被迫逐个执行。一个简单的修复方法是重写存储过程,并将一组Order id传递到存储过程中,而不是一次一个地这样做:1234567891011121314CREATE TYPE dbo.udt_OrderID_List AS TABLE( OrderID INT NOT NULL, PRIMARY KEY CLUSTERED ( OrderID ASC));GOCREATE TRIGGER TR_Sales_Orders_Process ON Sales.Orders AFTER INSERTASBEGIN SET NOCOUNT ON; DECLARE @OrderID_List dbo.udt_OrderID_List; EXEC dbo.process_order_fulfillment @OrderIDs = @OrderID_List;END更改的结果是将完整的id集合从触发器传递到存储过程并进行处理。只要存储过程以基于集合的方式管理这些数据,就可以避免重复执行,也就是说,避免在触发器内使用存储过程有很大的价值,因为它们添加了额外的封装层,进一步隐藏了在数据写入表时执行的TSQL。它们应该被认为是最后的手段,只有当可以在应用程序的许多地方多次重写TSQL时才使用。什么时候触发器是危险的架构师和开发人员面临的最大挑战之一是确保触发器只在需要时使用,而不允许它们成为一刀切的解决方案。向触发器添加TSQL通常被认为比向应用程序添加代码更快、更容易,但随着时间的推移,这样做的成本会随着每添加一行代码而增加。触发器在以下情况下会变得危险:保持尽可能少的触发以减少复杂性。触发代码变得复杂。如果更新表中的一行导致要执行数千行添加的触发器代码,那么开发人员就很难完全理解数据写入表时会发生什么。更糟糕的是,当出现问题时,故障排除非常具有挑战性。触发器跨服务器。这将网络操作引入到触发器中,可能导致在出现连接问题时写入速度变慢或失败。如果目标数据库是要维护的对象,那么即使是跨数据库触发器也会有问题。触发器调用触发器。触发器中最令人痛苦的是,当插入一行时,写操作会导致75个表中有100个触发器要执行。在编写触发器代码时,确保触发器可以执行所有必要的逻辑,而不会触发更多触发器。额外的触发通常是不必要的。递归触发器被设置为ON。这是一个默认设置为off的数据库级别设置。打开时,它允许触发器的内容调用相同的触发器。递归触发器会极大地损害性能,调试时也会非常混乱。通常,当一个触发器中的DML作为操作的一部分触发其他触发器时,使用递归触发器。函数、存储过程或视图都在触发器中。在触发器中封装更多的业务逻辑会使它们变得更复杂,并给人一种触发器代码短小简单的错误印象,而实际上并非如此。尽可能避免在触发器中使用存储过程和函数。迭代发生。循环和游标本质上是逐行操作的,可能会导致对1000行的操作一次触发1000次,这极大地损害了查询性能。这是一个很长的列表,但通常可以总结为短而简单的触发器会表现得更好,并避免上面的大多数陷阱。如果使用触发器来维护复杂的业务逻辑,那么随着时间的推移,越来越多的业务逻辑将被添加进来,并且不可避免地将违反上述最佳实践。重要的是要注意,为了维护原子的、事务,受触发器影响的任何对象都将保持事务处于打开状态,直到该触发器完成。这意味着长触发器不仅会使事务持续时间更长,而且还会持有锁并导致持续时间更长。因此,在测试触发器时,在为现有触发器创建或添加额外逻辑时,应该了解它们对锁、阻塞和等待的影响。
-
SQL Server触发器在非常有争议的主题。它们能以较低的成本提供便利,但经常被开发人员、DBA误用,导致性能瓶颈或维护性挑战。本文简要回顾了触发器,并深入讨论了如何有效地使用触发器,以及何时触发器会使开发人员陷入难以逃脱的困境。虽然本文中的所有演示都是在SQL Server中进行的,但这里提供的建议是大多数数据库通用的。触发器带来的挑战在MySQL、PostgreSQL、MongoDB和许多其他应用中也可以看到。什么是触发器可以在数据库或表上定义SQL Server触发器,它允许代码在发生特定操作时自动执行。本文主要关注表上的DML触发器,因为它们往往被过度使用。相反,数据库的DDL触发器通常更集中,对性能的危害更小。触发器是对表中数据更改时进行计算的一组代码。触发器可以定义为在插入、更新、删除或这些操作的任何组合上执行。MERGE操作可以触发语句中每个操作的触发器。触发器可以定义为INSTEAD OF或AFTER。AFTER触发器发生在数据写入表之后,是一组独立的操作,和写入表的操作在同一事务执行,但在写入发生之后执行。如果触发器失败,原始操作也会失败。INSTEAD OF触发器替换调用的写操作。插入、更新或删除操作永远不会发生,而是执行触发器的内容。触发器允许在发生写操作时执行TSQL,而不管这些写操作的来源是什么。它们通常用于在希望确保执行写操作时运行关键操作,如日志记录、验证或其他DML。这很方便,写操作可以来自API、应用程序代码、发布脚本,或者内部流程,触发器无论如何都会触发。触发器是什么样的用WideWorldImporters示例数据库中的Sales.Orders 表举例,假设需要记录该表上的所有更新或删除操作,以及有关更改发生的一些细节。这个操作可以通过修改代码来完成,但是这样做需要对表的代码写入中的每个位置进行更改。通过触发器解决这一问题,可以采取以下步骤:1. 创建一个日志表来接受写入的数据。下面的TSQL创建了一个简单日志表,以及一些添加的数据点:12345678910111213141516171819202122232425262728293031323334353637CREATE TABLE Sales.Orders_log( Orders_log_ID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Sales_Orders_log PRIMARY KEY CLUSTERED, OrderID int NOT NULL, CustomerID_Old int NOT NULL, CustomerID_New int NOT NULL, SalespersonPersonID_Old int NOT NULL, SalespersonPersonID_New int NOT NULL, PickedByPersonID_Old int NULL, PickedByPersonID_New int NULL, ContactPersonID_Old int NOT NULL, ContactPersonID_New int NOT NULL, BackorderOrderID_Old int NULL, BackorderOrderID_New int NULL, OrderDate_Old date NOT NULL, OrderDate_New date NOT NULL, ExpectedDeliveryDate_Old date NOT NULL, ExpectedDeliveryDate_New date NOT NULL, CustomerPurchaseOrderNumber_Old nvarchar(20) NULL, CustomerPurchaseOrderNumber_New nvarchar(20) NULL, IsUndersupplyBackordered_Old bit NOT NULL, IsUndersupplyBackordered_New bit NOT NULL, Comments_Old nvarchar(max) NULL, Comments_New nvarchar(max) NULL, DeliveryInstructions_Old nvarchar(max) NULL, DeliveryInstructions_New nvarchar(max) NULL, InternalComments_Old nvarchar(max) NULL, InternalComments_New nvarchar(max) NULL, PickingCompletedWhen_Old datetime2(7) NULL, PickingCompletedWhen_New datetime2(7) NULL, LastEditedBy_Old int NOT NULL, LastEditedBy_New int NOT NULL, LastEditedWhen_Old datetime2(7) NOT NULL, LastEditedWhen_New datetime2(7) NOT NULL, ActionType VARCHAR(6) NOT NULL, ActionTime DATETIME2(3) NOT NULL,UserName VARCHAR(128) NULL);该表记录所有列的旧值和新值。这是非常全面的,我们可以简单地记录旧版本的行,并能够通过将新版本和旧版本合并在一起来了解更改的过程。最后3列是新增的,提供了有关执行的操作类型(插入、更新或删除)、时间和操作人。2. 创建一个触发器来记录表的更改:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778CREATE TRIGGER TR_Sales_Orders_Audit ON Sales.Orders AFTER INSERT, UPDATE, DELETEASBEGIN SET NOCOUNT ON; INSERT INTO Sales.Orders_log (OrderID, CustomerID_Old, CustomerID_New, SalespersonPersonID_Old, SalespersonPersonID_New, PickedByPersonID_Old, PickedByPersonID_New, ContactPersonID_Old, ContactPersonID_New, BackorderOrderID_Old, BackorderOrderID_New, OrderDate_Old, OrderDate_New, ExpectedDeliveryDate_Old, ExpectedDeliveryDate_New, CustomerPurchaseOrderNumber_Old, CustomerPurchaseOrderNumber_New, IsUndersupplyBackordered_Old, IsUndersupplyBackordered_New, Comments_Old, Comments_New, DeliveryInstructions_Old, DeliveryInstructions_New, InternalComments_Old, InternalComments_New, PickingCompletedWhen_Old, PickingCompletedWhen_New, LastEditedBy_Old, LastEditedBy_New, LastEditedWhen_Old, LastEditedWhen_New, ActionType, ActionTime, UserName) SELECT ISNULL(Inserted.OrderID, Deleted.OrderID) AS OrderID, Deleted.CustomerID AS CustomerID_Old, Inserted.CustomerID AS CustomerID_New, Deleted.SalespersonPersonID AS SalespersonPersonID_Old, Inserted.SalespersonPersonID AS SalespersonPersonID_New, Deleted.PickedByPersonID AS PickedByPersonID_Old, Inserted.PickedByPersonID AS PickedByPersonID_New, Deleted.ContactPersonID AS ContactPersonID_Old, Inserted.ContactPersonID AS ContactPersonID_New, Deleted.BackorderOrderID AS BackorderOrderID_Old, Inserted.BackorderOrderID AS BackorderOrderID_New, Deleted.OrderDate AS OrderDate_Old, Inserted.OrderDate AS OrderDate_New, Deleted.ExpectedDeliveryDate AS ExpectedDeliveryDate_Old, Inserted.ExpectedDeliveryDate AS ExpectedDeliveryDate_New, Deleted.CustomerPurchaseOrderNumber AS CustomerPurchaseOrderNumber_Old, Inserted.CustomerPurchaseOrderNumber AS CustomerPurchaseOrderNumber_New,该触发器的唯一功能是将数据插入到日志表中,每行数据对应一个给定的写操作。它很简单,随着时间的推移易于记录和维护,表也会发生变化。如果需要跟踪其他详细信息,可以添加其他列,如数据库名称、服务器名称、受影响列的行数或调用的应用程序。
-
1、创建表的时候添加索引-- 创建表的时候添加索引-- INDEX 关键词-- myindex 索引的名称自己起的-- (username(16))添加到哪一个字段上CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX myindex (username(16)));2、创建表过后添加索引-- 添加索引-- myindex索引的名字(自己定义)-- mytable 表的名字CREATE INDEX myindex ON mytable(username(16));或者ALTER TABLE mytable ADD INDEX myindex(username);3 查看索引-- mytable 表的名字 show index FROM mytable;3、删除索引-- myindex索引的名字(自己定义)-- mytable 表的名字DROP INDEX myindex ON mytable;或者ALTER TABLE mytable DROP INDEX myindex;
-
DWS能否通过sql解锁用户
-
【功能模块】性能调优【操作步骤&问题现象】1、 分布存储和并发查询是高斯A(DWS)数据库的主要优势,也是它的最需要调优的点,网络Stream可能是超过其他资源问题的最大问题, DWS是否有相关的工具或界面可以监测到最大的或最可疑的网络流量 ,从而逐步定位出关联的SQL, 哪怕是多个SQL"合作"导致的,应该总有一个最耗网络资源的 ? 2、我们有同事总结了一些思路, 看下可行性及难点 : a. 查看流量大的网卡 (可能是每台主机) b. 查看这个网卡下的哪个端口 c. 查看流量大的端口上的进程 d. 通过进程找到对应的轻量级的线程号 e. 通过 pgxc_comm_client_info 查询轻量级线程号,找到对应的 tid , 通过tid 找到对应的session . 线程可能会比较多,到线程可能没法看到网络消耗了,只能看到cpu time消耗 , 这个可能与最初的找网络流量消耗不匹配。 涉及到多个DN , CN 上的线程,到底算一个,还是算总体消耗(一个session的总体),是个问题。 【截图信息】【日志信息】(可选,上传日志内容或者附件)
-
【功能模块】【flink sql】【 尝试 使用 huaweicloud-mrs-example-mrs-2.1】调flinksql???【操作步骤&问题现象】1、基于 huaweicloud-mrs-example-mrs-2.1 在 flink 1.7.2版本的 环境 运行 flink sql报错了?? 2、 测试 代码 package com.huawei.flink.example.sqljoin; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.TableEnvironment; import org.apache.flink.table.api.java.StreamTableEnvironment; //flink run -c com.huawei.flink.example.sqljoin.SqlSim -m yarn-cluster /srv/BigData/data1/task_script_dir/onedata_ec_analyse/flink/s5.jar public class SqlSim { public static final String KAFKA_TABLE_SOURCE_DDL = "" + "CREATE SOURCE STREAM stream_id (attr_name attr_type (',' attr_name attr_type)* )\n" + " WITH (\n" + " type = \"kafka\",\n" + " kafka_bootstrap_servers = \"\",\n" + " kafka_group_id = \"\",\n" + " kafka_topic = \"\",\n" + " encode = \"json\"\n" + " )\n" + " (TIMESTAMP BY timeindicator (',' timeindicator)?);timeindicator:PROCTIME '.' PROCTIME| ID '.' ROWTIME"; public static void main(String[] args) throws Exception{ System.err.println("--77777*--SqlSim--- "); StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); StreamTableEnvironment tEnv = TableEnvironment.getTableEnvironment(env); // ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); // BatchTableEnvironment tableEnv = BatchTableEnvironment.create(env); System.err.println("--35 *--SqlSim--- "); tEnv.sqlUpdate(KAFKA_TABLE_SOURCE_DDL); System.err.println("--38 38*--SqlSim--- "); env.execute(); System.err.println("--42 42*--SqlSim--- "); } }测试官网的例子" CREATE SOURCE STREAM stream_id (attr_name attr_type (',' attr_name attr_type)* ) WITH ( type = "kafka", kafka_bootstrap_servers = "", kafka_group_id = "", kafka_topic = "", encode = "json" ) (TIMESTAMP BY timeindicator (',' timeindicator)?);timeindicator:PROCTIME '.' PROCTIME| ID '.' ROWTIME【截图信息】【日志信息】(可选,上传日志内容或者附件)apache.flink.client.program.ProgramInvocationException: The main method caused an error. at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:546) at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:421) at org.apache.flink.client.program.ClusterClient.run(ClusterClient.java:430) at org.apache.flink.client.cli.CliFrontend.executeProgram(CliFrontend.java:814) at org.apache.flink.client.cli.CliFrontend.runProgram(CliFrontend.java:288) at org.apache.flink.client.cli.CliFrontend.run(CliFrontend.java:213) at org.apache.flink.client.cli.CliFrontend.parseParameters(CliFrontend.java:1051) at org.apache.flink.client.cli.CliFrontend.lambda$main$11(CliFrontend.java:1127) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1729) at org.apache.flink.runtime.security.HadoopSecurityContext.runSecured(HadoopSecurityContext.java:41) at org.apache.flink.client.cli.CliFrontend.main(CliFrontend.java:1127)Caused by: org.apache.flink.table.api.SqlParserException: SQL parse failed. Encountered "CREATE" at line 1, column 1.Was expecting one of: "SET" ... "RESET" ... "ALTER" ... "WITH" ... "+" ... "-" ... "NOT" ... "EXISTS" ... <UNSIGNED_INTEGER_LITERAL> ... <DECIMAL_NUMERIC_LITERAL> ... <APPROX_NUMERIC_LITERAL> ... <BINARY_STRING_LITERAL> ... <PREFIXED_STRING_LITERAL> ... <QUOTED_STRING> ... <UNICODE_STRING_LITERAL> ... "TRUE" ... "FALSE" ... "UNKNOWN" ... "NULL" ... <LBRACE_D> ... <LBRACE_T> ... <LBRACE_TS> ... "DATE" ... "TIME" ...
-
根据数据库的SQL执行机制以及大量的实践总结发现:通过一定的规则调整SQL语句, 在保证结果正确的基础上,能够提高SQL执行效率。1、 使用union all代替union union在合并两个集合时会执行去重操作,而union all则直接将两个结果集合并、 不执行去重。执行去重会消耗大量的时间,因此,在一些实际应用场景中,如果 通过业务逻辑已确认两个集合不存在重叠,可用union all替代union以便提升性 能。2、 join列增加非空过滤条件 若join列上的NULL值较多,则可以加上is not null过滤条件,以实现数据的提前过 滤,提高join效率。3、 not in转not exists not in语句需要使用nestloop anti join来实现,而not exists则可以通过hash anti join来实现。在join列不存在null值的情况下,not exists和not in等价。因此在确 保没有null值时,可以通过将not in转换为not exists,通过生成hash join来提升 查询效率。如下所示,如果t2.d2字段中没有null值(t2.d2字段在表定义中not null)查询可以修 改为 SELECT * FROM t1 WHERE NOT EXISTS (SELECT * FROM t2 WHERE t1.c1=t2.d2);产生的计划如下:● 选择hashagg。 查询中GROUP BY语句如果生成了groupagg+sort的plan性能会比较差,可以通过 加大work_mem的方法生成hashagg的plan,因为不用排序而提高性能。 ● 尝试将函数替换为case语句。 GaussDB A函数调用性能较低,如果出现过多的函数调用导致性能下降很多,可 以根据情况把可下推函数的函数改成CASE表达式。● 避免对索引使用函数或表达式运算。 对索引使用函数或表达式运算会停止使用索引转而执行全表扫描。● 尽量避免在where子句中使用!=或<>操作符、null值判断、or连接、参数隐式转 换。● 对复杂SQL语句进行拆分。 对于过于复杂并且不易通过以上方法调整性能的SQL可以考虑拆分的方法,把SQL 中某一部分拆分成独立的SQL并把执行结果存入临时表,拆分常见的场景包括但 不限于: – 作业中多个SQL有同样的子查询,并且子查询数据量较大。 – Plan cost计算不准,导致子查询hash bucket太小,比如实际数据1000W 行,hash bucket只有1000。 – 函数(如substr,to_number)导致大数据量子查询选择度计算不准。 – 多DN环境下对大表做broadcast的子查询。
-
DDL1、在GaussDB A中,建议DDL(建表、comments等)操作统一执行,在批 处理作业中尽量避免DDL操作。避免大量并发事务对性能的影响。2、在非日志表(unlogged table)使用完后,立即执行数据清理 (truncate)操作。因为在异常场景下,GaussDB A不保证非日志表(unlogged table)数据的安全性。3、临时表和非日志表的存储方式建议和基表相同。当基表为行存(列存) 表时,临时表和非日志表也推荐创建为行存(列存)表,可以避免行列混合关联 带来的高计算代价。4、索引字段的总长度不超过50字节。否则,索引大小会膨胀比较严重,带 来较大的存储开销,同时索引性能也会下降。5、不要使用DROP…CASCADE方式删除对象,除非已经明确对象间的依赖 关系,以免误删。数据加载和卸载1、在insert语句中显式给出插入的字段列表。例如: INSERT INTO task(name,id,comment) VALUES ('task1','100','第100个任务');2、在批量数据入库之后,或者数据增量达到一定阈值后,建议对表进行 analyze操作,防止统计信息不准确而导致的执行计划劣化。3、如果要清理表中的所有数据,建议使用truncate table方式,不要使用 delete table方式。delete table方式删除性能差,且不会释放那些已经删除了的 数据占用的磁盘空间。类型转换1、在需要数据类型转换(不同数据类型进行比较或转换)时,使用强制类 型转换,以防隐式类型转换结果与预期不符。2、在查询中,对常量要显式指定数据类型,不要试图依赖任何隐式的数据 类型转换。3、在ORACLE兼容模式下,在导入数据时,空字符串会自动转化为NULL。 如果需要保留空字符串需要新建兼容性为TD的数据库。查询操作1、除ETL程序外,应该尽量避免向客户端返回大量结果集的操作。如果结果 集过大,应考虑业务设计是否合理。2、使用事务方式执行DDL和DML操作。例如,truncate table、update table、delete table、drop table等操作,一旦执行提交就无法恢复。对于这类操 作,建议使用事务进行封装,必要时可以进行回滚。3、在查询编写时,建议明确列出查询涉及的所有字段,不建议使用 “SELECT *”这种写法。一方面基于性能考虑,尽量减少查询输出列;另一方面 避免增删字段对前端业务兼容性的影响。4、在访问表对象时带上schema前,可以避免因schema切换导致访问到 非预期的表。5、超过3张表或视图进行关联(特别是full join)时,执行代价难以估算。 建议使用WITH TABLE AS语句创建中间临时表的方式增加SQL语句的可读性。6、尽量避免使用笛卡尔积和Full join。这些操作会造成结果集的急剧膨胀, 同时其执行性能也很低。7、NULL值的比较只能使用IS NULL或者IS NOT NULL的方式判断,其他任 何形式的逻辑判断都返回NULL。例如:NULL<>NULL、NULL=NULL和NULL<>1 返回结果都是NULL,而不是期望的布尔值。8、需要统计表中所有记录数时,不要使用count(col)来替代count(*)。 count(*)会统计NULL值(真实行数),而count(col)不会统计。9、在执行count(col)时,将“值为NULL”的记录行计数为0。在执行 sum(col)时,当所有记录都为NULL时,终将返回NULL;当不全为NULL时, “值为NULL”的记录行将被计数为0。10、count(多个字段)时,多个字段名必须用圆括号括起来。例如, count( (col1,col2,col3) )。注意:通过多字段统计行数时,即使所选字段都为 NULL,该行也被计数,效果与count(*)一致。11、count(distinct col)用来计算该列不重复的非NULL的数量,NULL将不被 计数。12、count(distinct (col1,col2,...))用来统计多列的唯一值数量,当所有统计字 段都为NULL时,也会被计数,同时这些记录被认为是相同的。13、尽量避免标量子查询语句的出现。标量子查询是出现在select语句输出列 表中的子查询,在下面例子中,下划线部分即为一个标量子查询语句:SELECT id, (SELECT COUNT(*) FROM films f WHERE f.did = s.id) FROM staffs_p1 s;标量子查询往往会导致查询性能急剧劣化,在应用开发过程中,应当根据业务逻 辑,对标量子查询进行等价转换,将其写为表关联。14、在where子句中,应当对过滤条件进行排序,把选择读较小(筛选出的 记录数较少)的条件排在前面。15、where子句中的过滤条件,尽量符合单边规则。即把字段名放在比较条 件的一边,优化器在某些场景下会自动进行剪枝优化。形如col op expression, 其中col为表的一个列,op为‘=’、‘>’的等比较操作符,expression为不含列 名的表达式。例如, SELECT id, from_image_id, from_person_id, from_video_id FROM face_data WHERE current_timestamp(6) - time < '1 days'::interval;改写为: SELECT id, from_image_id, from_person_id, from_video_id FROM face_data where time > current_timestamp(6) - '1 days'::interval;16、尽量避免不必要的排序操作。排序需要耗费大量的内存及CPU,如果业 务逻辑许可,可以组合使用order by和limit,减小资源开销。GaussDB A默认按 照ASC & NULL LAST进行排序。17、使用ORDER BY子句进行排序时,显式指定排序方式(ASC/DESC), NULL的排序方式(NULL FIRST/NULL LAST)。18、不要单独依赖limit子句返回特定顺序的结果集。如果部分特定结果集, 可以将ORDER BY子句与Limit子句组合使用,必要时也可以使用offset跳过特定结 果。19、在保障业务逻辑准确的情况下,建议尽量使用UNION ALL来代替 UNION。20、如果过滤条件只有OR表达式,可以将OR表达式转化为UNION ALL以提 升性能。使用OR的SQL语句经常无法优化,导致执行速度慢。例如,将下面语句 SELECT * FROM scdc.pub_menu WHERE (cdp= 300 AND inline=301) OR (cdp= 301 AND inline=302) OR (cdp= 302 AND inline=301);转换为: SELECT * FROM scdc.pub_menu WHERE (cdp= 300 AND inline=301) union all SELECT * FROM scdc.pub_menu WHERE (cdp= 301 AND inline=302) union all SELECT * FROM tablename WHERE (cdp= 302 AND inline=301)21、当in(val1, val2, val3…)表达式中字段较多时,建议使用in (values (va11), (val2),(val3)…)语句进行替换。优化器会自动把in约束转换为非关联子查 询,从而提升查询性能。22、在关联字段不存在NULL值的情况下,使用(not) exist代替(not) in。例 如,在下面查询语句中,当T1.C1列不存在NULL值时,可以先为T1.C1字段添加 NOT NULL约束,再进行如下改写。SELECT * FROM T1 WHERE T1.C1 NOT IN (SELECT T2.C2 FROM T2);可以改写为: SELECT * FROM T1 WHERE NOT EXISTS (SELECT * FROM T1,T2 WHERE T1.C1=T2.C2);23、通过游标进行翻页查询,而不是使用LIMIT OFFSET语法,避免多次执行 带来的资源开销。游标必须在事务中使用,执行完后务必关闭游标并提交事务。
-
AND 和 OR 运算符AND 和 OR 可在 WHERE 子语句中把两个或多个条件结合起来。如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。原始的表 (用在例子中的):LastNameFirstNameAddressCityAdamsJohnOxford StreetLondonBushGeorgeFifth AvenueNew YorkCarterThomasChangan StreetBeijingCarterWilliamXuanwumen 10BeijingAND 运算符实例使用 AND 来显示所有姓为 "Carter" 并且名为 "Thomas" 的人:SELECT * FROM Persons WHERE FirstName='Thomas' AND LastName='Carter'结果:LastNameFirstNameAddressCityCarterThomasChangan StreetBeijingOR 运算符实例使用 OR 来显示所有姓为 "Carter" 或者名为 "Thomas" 的人:SELECT * FROM Persons WHERE firstname='Thomas' OR lastname='Carter'结果:LastNameFirstNameAddressCityCarterThomasChangan StreetBeijingCarterWilliamXuanwumen 10Beijing结合 AND 和 OR 运算符我们也可以把 AND 和 OR 结合起来(使用圆括号来组成复杂的表达式):SELECT * FROM Persons WHERE (FirstName='Thomas' OR FirstName='William')AND LastName='Carter'结果:LastNameFirstNameAddressCityCarterThomasChangan StreetBeijingCarterWilliamXuanwumen 10Beijing
-
后台超长会话清理GaussDB(DWS)即席访问或开发测试环境,经常遇到低效SQL长时间执行,占用大量系统资源导致系统运行效率变低。因此在排查系统资源占用过高,性能不足的场景时经常需要检查长时间未执行完的低效SQL予以清理,以释放系统资源提高性能。查询及清理语句-- 查询持续运行时间超过5小时的会话SELECT * FROM pg_stat_activity WHERE useName <> 'Ruby' and state <> 'idle' and current_timestamp - query_start > interval '5 hours';--会话清理SELECT PG_TERMINATE_BACKEND(pid) FROM pg_stat_activity WHERE useName <> 'Ruby' and state <> 'idle' and current_timestamp - query_start > interval '1 days';
-
【功能模块】我们要调 flink sql 例子, huaweicloud-mrs-example有好几个分支,怎么知道用哪个分支?【操作步骤&问题现象】1、 导入了 https://github.com/huaweicloud/huaweicloud-mrs-example/branches 的 mrs-3.0.2Updated last mont 分支 Compar2、 测试 flink run -m yarn-cluster --class com.huawei.bigdata.flink.examples.JavaStreamSqlExample ./../tmp/s.jar测试 com.huawei.bigdata.flink.examples.JavaStreamSqlExample的 例子,不通过 【截图信息】【日志信息】(可选,上传日志内容或者附件)bin/flink run --class com.huawei.bigdata.flink.examples.JavaStreamSqlExample <path of StreamSqlExample jar>*********************************************************************************java.lang.NoClassDefFoundError: org/apache/flink/table/factories/StreamTableSourceFactory at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) at java.net.URLClassLoader.access$100(URLClassLoader.java:74) at java.net.URLClassLoader$1.run(URLClassLoader.java:369) at java.net.URLClassLoader$1.run(URLClassLoader.java:363) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:362) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) at java.net.URLClassLoader.access$100(URLClassLoader.java:74) at java.net.URLClassLoader$1.run(URLClassLoader.java:369) at java.net.URLClassLoader$1.run(URLClassLoader.java:363) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:362) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:411) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:370) at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) at java.util.ServiceLoader$1.next(ServiceLoader.java:480) at java.util.Iterator.forEachRemaining(Iterator.java:116) at org.apache.flink.table.factories.TableFactoryService.discoverFactories(TableFactoryService.java:214) at org.apache.flink.table.factories.TableFactoryService.findAllInternal(TableFactoryService.java:170) at org.apache.flink.table.factories.TableFactoryService.findAll(TableFactoryService.java:125) at org.apache.flink.table.factories.ComponentFactoryService.find(ComponentFactoryService.java:48) at org.apache.flink.table.api.java.internal.StreamTableEnvironmentImpl.lookupExecutor(StreamTableEnvironmentImpl.java:143) at org.apache.flink.table.api.java.internal.StreamTableEnvironmentImpl.create(StreamTableEnvironmentImpl.java:118) at org.apache.flink.table.api.java.StreamTableEnvironment.create(StreamTableEnvironment.java:112) at com.huawei.bigdata.flink.examples.JavaStreamSqlExample.main(JavaStreamSqlExample.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:529) at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:421) at org.apache.flink.client.program.ClusterClient.run(ClusterClient.java:430) at org.apache.flink.client.cli.CliFrontend.executeProgram(CliFrontend.java:814) at org.apache.flink.client.cli.CliFrontend.runProgram(CliFrontend.java:288) at org.apache.flink.client.cli.CliFrontend.run(CliFrontend.java:213) at org.apache.flink.client.cli.CliFrontend.parseParameters(CliFrontend.java:1051) at org.apache.flink.client.cli.CliFrontend.lambda$main$11(CliFrontend.java:1127) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1729) at org.apache.flink.runtime.security.HadoopSecurityContext.runSecured(HadoopSecurityContext.java:41) at org.apache.flink.client.cli.CliFrontend.main(CliFrontend.java:1127)Caused by: java.lang.ClassNotFoundException: org.apache.flink.table.factories.StreamTableSourceFactory at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
-
【操作步骤&问题现象】(由于业务测sql关联好几十张表做关联查询导致内存使用率过高,目前用4张为例子)打个比方 如果有4张表 有两张账户表 hash分布键是一样 1000万数据,有两个用户表 hash分布键一样 500万数据 账户表与用户表键值不同,目前查看是 select 4 张表做关联,优化方向:1、select(两张客户表) join select(两张用户表),2、分别写成2个查询,并插入临时表进行查询 或者别的优化方向,求大佬分析问题:gaussdb sql优化需要小表驱动大表么,有无查询表顺序问题,如果不需要业务侧,想了解gaussdb查询对内存的消耗以及算法
-
如果不涉及时间部分,那么我们可以轻松地比较两个日期!假设我们有下面这个 "Orders" 表:OrderIdProductNameOrderDate1computer2008-12-262printer2008-12-263electrograph2008-11-124telephone2008-10-19现在,我们希望从上表中选取 OrderDate 为 "2008-12-26" 的记录。我们使用如下 SELECT 语句:SELECT * FROM Orders WHERE OrderDate='2008-12-26'结果集:OrderIdProductNameOrderDate1computer2008-12-263electrograph2008-12-26现在假设 "Orders" 类似这样(请注意 "OrderDate" 列中的时间部分):OrderIdProductNameOrderDate1computer2008-12-26 16:23:552printer2008-12-26 10:45:263electrograph2008-11-12 14:12:084telephone2008-10-19 12:56:10如果我们使用上面的 SELECT 语句:SELECT * FROM Orders WHERE OrderDate='2008-12-26'那么我们得不到结果。这是由于该查询不含有时间部分的日期。提示:如果您希望使查询简单且更易维护,那么请不要在日期中使用时间部分!
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签