- 浏览: 228026 次
- 性别:
- 来自: 重庆
-
文章分类
最新评论
-
fitzsu:
关于中文占多少字节的问题应该是跟字符集相关的,跟类型无关的对吗 ...
Oracle CHAR,VARCHAR,VARCHAR2,nvarchar类型的区别与使用 -
showzh:
...
Oracle CHAR,VARCHAR,VARCHAR2,nvarchar类型的区别与使用 -
ltian:
实话实说,让我云里雾里!不知道Hibernate缓存能力和云计 ...
OO + 分布式计算 = 软件架构的方向 -
蔡华江:
5.如果数据间引用不存在环路,还可以用递归查询来完成如果出现环 ...
一道数据库开发面试题 -
zydar:
自己不改~
springside3版本qWikiOffice
binding in-lists in 10g
This article demonstrates a new method for binding IN-lists in 10g, using the new collection condition MEMBER OF. Also included is a common pre-10g method and a performance comparison (with dramatic results which leads me to conclude that MEMBER OF is much simpler to use but should only be used with very small sets or lists).
Incidentally, how to bind IN-lists (i.e. how to pass a list of values in one parameter and have Oracle treat the single parameter as a list) is a common problem cited on many web forums. Unfortunately, what many developers do is construct a dynamic SQL statement and concatenate a delimited string to the end to represent the list of values. In addition to shifting from static to dynamic SQL, this approach also makes it impossible to use bind variables and, for form-based applications, also leaves the application wide open to SQL injection. An alternative to this is to turn the delimited string into a collection first and reference the collection in the SQL.
In this article, we will use examples that pass collections of data as IN-lists, rather than lists of values composed as delimited strings.
setup
First we will create some simple collection types to use in our examples, as follows.
SQL> CREATE OR REPLACE TYPE varchar2_ntt AS TABLE OF VARCHAR2(4000); 2 / Type created.
SQL> CREATE OR REPLACE TYPE number_ntt AS TABLE OF NUMBER; 2 / Type created.
in-list binding in previous versions
The correct way to bind an in-list, regardless of Oracle version from 8.0 onwards, is to have the list-values passed as a collection. We can then cast the collection to a pseudo-table (using the TABLE operator). We will see an example of this below. First we will create a simple procedure to find all objects in a list of categories. The list of categories will be passed to our procedure as a collection.
SQL> CREATE PROCEDURE which_objects( which_types_in IN varchar2_ntt ) AS 2 BEGIN 3 FOR r IN (SELECT object_name 4 FROM user_objects 5 WHERE object_type IN (SELECT column_value 6 FROM TABLE(which_types_in))) 7 LOOP 8 DBMS_OUTPUT.PUT_LINE( r.object_name ); 9 END LOOP; 10 END; 11 / Procedure created.
Our client program generates the "in-list" collection and calls the procedure, as follows.
SQL> DECLARE 2 nt_types varchar2_ntt := varchar2_ntt('TABLE','TYPE','PACKAGE'); 3 BEGIN 4 which_objects( which_types_in => nt_types ); 5 END; 6 / TGT PLSQL_PROFILER_DATA PLSQL_PROFILER_UNITS SRC PROF_REPORT_UTILITIES PLSQL_PROFILER_RUNS PKG XPLAN_OT XPLAN_NTT XPLAN NUMBER_NTT VARCHAR2_NTT ETL_PKG PL/SQL procedure successfully completed.
in-list binding in 10g
We will now see the 10g alternative using the new MEMBER OF condition for collections. The syntax is very simple and doesn't require us to cast the collection to a pseudo-table.
SQL> CREATE PROCEDURE which_objects_10g( which_types_in IN varchar2_ntt ) AS 2 BEGIN 3 FOR r IN (SELECT object_name 4 FROM user_objects 5 WHERE object_type MEMBER OF which_types_in) 6 LOOP 7 DBMS_OUTPUT.PUT_LINE( r.object_name ); 8 END LOOP; 9 END; 10 / Procedure created.
We call this version of the procedure in the same way, as follows.
SQL> DECLARE 2 nt_types varchar2_ntt := varchar2_ntt('TABLE','TYPE','PACKAGE'); 3 BEGIN 4 which_objects_10g( which_types_in => nt_types ); 5 END; 6 / TGT PLSQL_PROFILER_DATA PLSQL_PROFILER_UNITS SRC PROF_REPORT_UTILITIES PLSQL_PROFILER_RUNS PKG XPLAN_OT XPLAN_NTT XPLAN NUMBER_NTT VARCHAR2_NTT ETL_PKG PL/SQL procedure successfully completed.
a simple performance test
We will compare the new and old methods for IN-list binding under a couple of simple scenarios, as follows:
- constraining a SQL statement as an IN-list; and
- testing a literal value against an IN-list in PL/SQL.
test one: filtering a table based on an in-list
For our first performance test, we will compare methods for binding an IN-list to a SQL statement, using a version of Tom Kyte's RUNSTATS utility. We will create a table with 1 million rows and query it with an IN-list collection of approximately 100 keys. First, we create the sample table as follows.
SQL> CREATE TABLE million_rows 2 AS 3 SELECT ROWNUM AS id 4 , RPAD('x',100) AS data 5 FROM dual 6 CONNECT BY ROWNUM < 1000000; Table created. SQL> ALTER TABLE million_rows ADD 2 CONSTRAINT million_rows_pk 3 PRIMARY KEY (id); Table altered. SQL> BEGIN 2 DBMS_STATS.GATHER_TABLE_STATS( 3 USER, 'MILLION_ROWS', estimate_percent=>100 4 ); 5 END; 6 / PL/SQL procedure successfully completed.
We will now create a small procedure to compare the new and old methods. This procedure will load a collection with a parameterised sample of IDs to test the TABLE operator and MEMBER OF condition at different volumes.
SQL> CREATE PROCEDURE compare_in_list( sample_in IN NUMBER ) IS 2 3 nt_ids number_ntt := number_ntt(); 4 5 TYPE million_rows_aat IS TABLE OF million_rows%ROWTYPE 6 INDEX BY PLS_INTEGER; 7 aa_rows million_rows_aat; 8 9 BEGIN 10 11 /* Fetch a sample of data to use as the in-list... */ 12 EXECUTE IMMEDIATE 13 'SELECT id FROM million_rows SAMPLE (' || sample_in || ')' 14 BULK COLLECT INTO nt_ids; 15 16 DBMS_OUTPUT.PUT_LINE( 'IN-list size : ' || nt_ids.COUNT ); 17 18 runstats_pkg.rs_start; 19 20 /* Fetch the matching records using the TABLE method... */ 21 SELECT * BULK COLLECT INTO aa_rows 22 FROM million_rows 23 WHERE id IN (SELECT column_value FROM TABLE(CAST(nt_ids AS number_ntt))); 24 25 runstats_pkg.rs_middle; 26 27 /* ...and the 10g MEMBER method... */ 28 SELECT * BULK COLLECT INTO aa_rows 29 FROM million_rows 30 WHERE id MEMBER OF nt_ids; 31 32 runstats_pkg.rs_stop(1000); 33 34 END; 35 / Procedure created.
We will test with a small sample of the MILLION_ROWS table (representing an IN-list of approximately 100 rows), as follows.
SQL> exec compare_in_list( 0.01 ); IN-list size : 107 Run1 ran in 110 hsecs Run2 ran in 1606 hsecs Run1 ran in 6.85% of the time Name Run1 Run2 Diff STAT..recursive cpu usage 3 1,230 1,227 LATCH.multiblock read objects 0 2,156 2,156 LATCH.simulator hash latch 111 3,907 3,796 STAT..physical reads cache pre 0 14,112 14,112 STAT..free buffer inspected 128 15,169 15,041 STAT..consistent gets 323 15,396 15,073 STAT..consistent gets from cac 323 15,396 15,073 STAT..session logical reads 323 15,396 15,073 STAT..free buffer requested 101 15,195 15,094 STAT..physical reads 101 15,195 15,094 STAT..physical reads cache 101 15,195 15,094 LATCH.cache buffers lru chain 105 15,264 15,159 STAT..no work - consistent rea 1 15,385 15,384 STAT..table scan blocks gotten 0 15,385 15,385 LATCH.object queue header oper 210 30,458 30,248 LATCH.cache buffers chains 623 46,141 45,518 STAT..table scan rows gotten 0 1,000,000 1,000,000 Run1 latches total versus run2 -- difference and pct Run1 Run2 Diff Pct 1,435 99,876 98,441 1.44% PL/SQL procedure successfully completed.
We can see a dramatic difference in performance between the two methods, with the new MEMBER OF condition taking 16 times longer than when we queried the collection as a pseudo-table. The key to this lack of performance is evident in the statistics, particularly the "table scan rows gotten". This indicates that Oracle is using a full table scan with the MEMBER OF method. We can verify this below with EXPLAIN PLAN (although we will use a literal collection rather than a bind variable for convenience).
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'MEMBER' FOR 2 SELECT * 3 FROM million_rows 4 WHERE id MEMBER OF number_ntt(1,2,3); Explained. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'MEMBER')); PLAN_TABLE_OUTPUT -------------------------------------------------- Plan hash value: 1095651555 -------------------------------------------------- ... | Id | Operation | Name | Rows | ... -------------------------------------------------- ... | 0 | SELECT STATEMENT | | 50000 | ... |* 1 | TABLE ACCESS FULL| MILLION_ROWS | 50000 | ... -------------------------------------------------- ... Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ID"MEMBER OF"NUMBER_NTT"(1,2,3)) 13 rows selected.
As indicated by the RUNSTATS results, Oracle has chosen a full table scan for the query, with an estimated cardinality of 50,000 (a 20% selectivity) for the filter. We can compare this with the CBO's treatment of a normal IN-list, as follows.
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'IN' FOR 2 SELECT * 3 FROM million_rows 4 WHERE id IN (1,2,3); Explained. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'IN')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------- Plan hash value: 127701680 ---------------------------------------------------------------- ... | Id | Operation | Name | Rows | ... ---------------------------------------------------------------- ... | 0 | SELECT STATEMENT | | 3 | ... | 1 | INLIST ITERATOR | | | ... | 2 | TABLE ACCESS BY INDEX ROWID| MILLION_ROWS | 3 | ... |* 3 | INDEX RANGE SCAN | MILLION_ROWS_PK | 3 | ... ---------------------------------------------------------------- ... Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("ID"=1 OR "ID"=2 OR "ID"=3) 15 rows selected.
Oracle is able to recognise the list of literal values in this case and make the correct cardinality estimates, leading to an index range scan. Of course, this article is about parameterised IN-lists, so if we compare the new MEMBER method with the original TABLE operator method, we can see that Oracle handles the collection in a very different way.
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'TABLE' FOR 2 SELECT * 3 FROM million_rows 4 WHERE id IN (SELECT column_value FROM TABLE(number_ntt(1,2,3))); Explained. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'TABLE')); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------- Plan hash value: 3090652353 --------------------------------------------------------------------------- ... | Id | Operation | Name | Rows | ... --------------------------------------------------------------------------- ... | 0 | SELECT STATEMENT | | 255 | ... | 1 | NESTED LOOPS | | 255 | ... | 2 | SORT UNIQUE | | | ... | 3 | COLLECTION ITERATOR CONSTRUCTOR FETCH| | | ... | 4 | TABLE ACCESS BY INDEX ROWID | MILLION_ROWS | 1 | ... |* 5 | INDEX UNIQUE SCAN | MILLION_ROWS_PK | 1 | ... --------------------------------------------------------------------------- ... Predicate Information (identified by operation id): --------------------------------------------------- 5 - access("ID"=VALUE(KOKBF$)) 17 rows selected.
With the TABLE operator method, Oracle chooses a nested loops join using the unique index on MILLION_ROWS, hence the major performance improvement. This is due to the semantic difference between the two methods. With the TABLE operator, Oracle unnests the values from the collection and then uses these to probe the MILLION_ROWS_PK index. With the MEMBER condition, however, we only have a filter condition, not a join. We are asking for records from MILLION_ROWS where the ID is in the collection, rather than the other way round. This means that Oracle must probe the collection with values from the MILLION_ROWS.ID column. This has a dramatic effect on performance and there seems to be no way to reverse this behaviour.
There are a number of ways we can try to correct the cardinality or force Oracle to use an index, for example:
- OPT_ESTIMATE hint, e.g.
/*+ OPT_ESTIMATE(table, million_rows, scale_rows=0.0001) */
; - CARDINALITY hint, e.g.
/*+ CARDINALITY(million_rows, 3) */
; - FIRST_ROWS hint;
- INDEX or INDEX_RS hints, e.g.
INDEX(_RS)(million_rows, million_rows_pk)
; - OPTIMIZER_INDEX_COST_ADJ parameter, e.g.
ALTER SESSION SET optimizer_index_cost_adj = 5
.
With any of these methods, Oracle will not rewrite our query in any way. There simply is no way around the fact that we are filtering MILLION_ROWS against the collection. The best we can achieve is an index full scan, forced by an appropriate hint, as follows.
SQL> EXPLAIN PLAN SET STATEMENT_ID = 'INDEX' FOR 2 SELECT /*+ INDEX(million_rows) */ * 3 FROM million_rows 4 WHERE id MEMBER OF number_ntt(1,2,3); Explained. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'INDEX')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------- Plan hash value: 857746450 --------------------------------------------------------------- ... | Id | Operation | Name | Rows | ... --------------------------------------------------------------- ... | 0 | SELECT STATEMENT | | 50000 | ... | 1 | TABLE ACCESS BY INDEX ROWID| MILLION_ROWS | 50000 | ... |* 2 | INDEX FULL SCAN | MILLION_ROWS_PK | 50000 | ... --------------------------------------------------------------- ... Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("ID"MEMBER OF"NUMBER_NTT"(1,2,3)) 14 rows selected.
It appears that an index range scan is simply not available as an access path when using this new condition, because Oracle will not reverse the direction of the filter.
The above performance tests were conducted using many probes of a small collection. It follows, therefore, that the larger the collection, the greater the disparity in performance between TABLE and MEMBER, with the latter becoming almost unusable. Some example timings are as follows.
Sample Size | IN-List Size | IN TABLE() (s) | MEMBER OF (s) |
0.001 | 5 | 0.1 | 5.1 |
0.01 | 107 | 1.1 | 16.1 |
0.1 | 984 | 13.7 | 107.2 |
1.0 | 10,000 | 21.4 | >1,200 |
Note that this behaviour was last tested on an 11g Release 1 database (11.1.0.6) and it is unchanged.
test two: probing an in-list with a single value
The previous tests measured the performance of a parameterised IN-list in SQL, which is the most common application for this technique. However, we can also use the MEMBER condition in PL/SQL tests. For our second performance test, we will repeatedly probe a parameterised list with a single value, again comparing the original TABLE operator with the new MEMBER condition. For completeness, we will also measure the performance of a loop through the parameterised list to search for the single value. We will use an anonymous block for these tests, as follows.
SQL> DECLARE 2 in_list number_ntt := number_ntt(); 3 v_cnt PLS_INTEGER; 4 v_hits PLS_INTEGER := 0; 5 BEGIN 6 7 /* Add 100 elements to the collection "IN-list"... */ 8 in_list.EXTEND(100); 9 FOR i IN 1 .. 100 LOOP 10 in_list(i) := i; 11 END LOOP; 12 13 /* TABLE operator... */ 14 timer.snap; 15 FOR i IN 1 .. 10000 LOOP 16 SELECT COUNT(*) INTO v_cnt FROM TABLE(in_list) WHERE column_value = i; 17 IF v_cnt > 0 THEN 18 v_hits := v_hits + 1; 19 END IF; 20 END LOOP; 21 timer.show('TABLE (hits=' || v_hits || ')'); 22 23 /* MEMBER condition... */ 24 v_hits := 0; 25 timer.snap; 26 FOR i IN 1 .. 10000 LOOP 27 IF i MEMBER OF in_list THEN 28 v_hits := v_hits + 1; 29 END IF; 30 END LOOP; 31 timer.show('MEMBER (hits=' || v_hits || ')'); 32 33 /* Collection loop... */ 34 v_hits := 0; 35 timer.snap; 36 FOR i IN 1 .. 10000 LOOP 37 FOR ii IN 1 .. in_list.COUNT LOOP 38 IF i = in_list(ii) THEN 39 v_hits := v_hits + 1; 40 EXIT; 41 END IF; 42 END LOOP; 43 END LOOP; 44 timer.show('LOOP (hits=' || v_hits || ')'); 45 46 END; 47 / [TABLE (hits=100)] 1.22 seconds [MEMBER (hits=100)] 0.04 seconds [LOOP (hits=100)] 0.21 seconds PL/SQL procedure successfully completed.
As there is no table access involved, we have used a simple TIMER package to measure relative performance. We can see that for this type of IN-list probing, the new MEMBER condition is more efficient and effective than any other method, so it might be worth using this technique under certain circumstances.
further reading
For a good discussion of techniques for binding IN-lists prior to 10g, particularly when they are supplied as delimited strings instead of collections, see this article by William Robertson. For more information on new collection conditions and operators in 10g, see this oracle-developer.net article . The TIMER and RUNSTATS packages used in the performance tests for this article can be found on the Utilities page of this site.
source code
The source code for the examples in this article can be downloaded from here .
Adrian Billington, June 2004 (updated September 2008)
原文:http://www.oracle-developer.net/display.php?id=301
发表评论
-
嵌套表与索引表
2010-03-18 17:43 1072两者都可以用来存储数组.嵌套表更像通常的数组,因为它的下标固定 ... -
Oracle CHAR,VARCHAR,VARCHAR2,nvarchar类型的区别与使用
2009-12-03 18:39 28916一 varchar,nvarchar, 四个类 ... -
Oracle数据字典
2009-12-03 17:17 1038以下表格中收集了Oracle数据字典中几乎所有的视图或别名,至 ... -
Oracle 中重新编译无效的存储过程, 或函数、触发器等对象
2009-12-03 16:42 3993Oracle 中的存储过程在有些情况下会变成失效状态,在 PL ... -
ORACLE动态调用存储过程
2009-12-03 16:40 1578ORACLE动态调用存储过程 SQL> create ... -
Oracle 正则表达式
2009-12-02 18:46 1920Oracle 正则表达式 就是 ... -
有效创建oracle dblink 的两种方式
2009-12-02 18:14 1078有效创建oracle dblin ... -
blobtoclob
2009-12-02 18:13 741create or replace function F(B ... -
修改序列
2009-12-02 18:12 1259create or replace procedure p_m ... -
内存表
2009-12-02 18:11 1218内存表 我们知道, oracle, sqlserver等关系 ... -
Oracle中start with...connect by prior子句用法
2009-11-30 17:16 1005Oracle中start with...connect by ... -
Oracle DML 子句 RETURNING INTO
2009-11-30 10:36 2457The RETURNING INTO clause al ...
相关推荐
1、文件说明: Centos8操作系统texmacs-fedora-fonts-2.1-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf texmacs-fedora-fonts-2.1-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
内容概要:本文详细介绍了如何使用Matlab/Simulink对直流电动机双闭环调速系统进行建模与仿真。文中首先解释了双闭环调速系统的原理,即通过转速外环和电流内环的协同工作,使电机快速达到并维持稳定的运行状态。接着,逐步指导读者在Simulink中搭建模型,包括设置信号源、配置PI控制器参数、选择电机模块以及连接各个组件。此外,还提供了具体的参数设置示例和优化技巧,如调整PI控制器的比例系数和积分系数,确保系统的快速响应和平稳过渡。最后,通过对仿真结果的分析,展示了双闭环调速系统的优势及其在实际应用中的价值。 适合人群:从事电力电子实验的研究人员和技术爱好者,尤其是那些希望深入了解直流电动机控制系统原理的人。 使用场景及目标:适用于需要精确控制直流电动机转速的应用场合,如工业自动化设备、机器人等领域。通过学习本文,读者可以掌握使用Matlab/Simulink进行系统建模和仿真的方法,提高对复杂控制系统的理解和应用能力。 其他说明:文中提到的一些参数设置和优化技巧来源于实践经验,对于初学者来说可能需要多次尝试才能找到最适合自己的解决方案。同时,在撰写相关实验报告时,可以根据提供的建议整理和展示仿真数据,以便更好地表达研究成果。
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
内容概要:本文档详细介绍了Proxmox网络组件(vmbr、SDN)、Linux网络基础(桥接、VLAN、Bonding)以及虚拟化网络模型的核心概念,并通过一系列课后习题及其答案帮助读者巩固所学知识。第一部分讲解了Linux网桥与物理交换机的异同、桥接设备的配置方法、VLAN的相关概念及配置步骤;第二部分探讨了Proxmox中vmbr0的作用和创建新桥接接口的方法,以及SDN的核心组件和多租户场景下的优势;第三部分对比了桥接模型与NAT模型的适用场景及局限性,并提供了虚拟机无法访问互联网的排查步骤;第四部分通过故障案例分析和设计题,进一步加深对网络隔离和SDN网络设计的理解。 适合人群:具有Linux和网络基础知识的IT技术人员,特别是从事虚拟化、网络管理和云计算领域的工程师。 使用场景及目标:① 掌握Linux网络基础,包括桥接、VLAN、Bonding的配置与原理;② 理解Proxmox网络组件的功能及配置方法;③ 学习虚拟化网络模型的不同应用场景及优缺点;④ 提升网络故障排查能力和复杂网络的设计能力。 阅读建议:此文档不仅提供了理论知识,还结合了大量实际操作题目,建议读者在学习过程中动手实践,通过配置真实环境来加深理解。同时,对于关键知识点,可以查阅相关资料进行补充学习。
立式插秧机sw16可编辑_三维3D设计图纸_包括零件图_机械3D图可修改打包下载_三维3D设计图纸_包括零件图_机械3D图可修改打包下载.zip
内容概要:本文深入探讨了A*算法和跳点搜索算法(JPS+)在机器人路径规划领域的应用及其与动态窗口算法(DWA)相结合的改进。首先介绍了A*算法的基本原理和实现方式,然后详细解释了JPS+算法如何通过跳点搜索提高效率。接着讨论了这两种算法与DWA结合的具体方法,特别是在多机器人场景下的路径冲突避免和动态避障策略。文中还展示了多种改进措施的效果,如通过八叉树预处理地图、引入朝向变化惩罚以及采用异步优先级协商机制等。最后比较了单机器人和多机器人场景下的性能差异,强调了算法选择的重要性。 适合人群:从事机器人技术研发的专业人士,尤其是关注路径规划算法的研究人员和技术开发者。 使用场景及目标:适用于希望深入了解并优化机器人路径规划系统的团队和个人。目标是在单机器人和多机器人场景中提升路径规划的效率和灵活性,确保机器人能够在复杂的环境中稳定运行。 其他说明:文章不仅提供了理论分析,还包括了大量的代码片段和实际案例,有助于读者更好地理解和应用这些先进的路径规划技术。
内容概要:本文深入探讨了转差频率控制的异步电机矢量控制系统仿真模型。首先介绍了转差频率控制的基本原理,即通过控制转差频率间接调控电机转矩。接着阐述了矢量控制的思想,即将定子电流分解为励磁和转矩两个独立控制的分量。随后展示了仿真模型的具体实现,包括电机参数设定、状态空间模型构建、PI控制器参数配置以及关键模块如转差频率计算、坐标变换、磁链观测等的代码示例。最后强调了配套的50页说明文档对于理解和调试模型的重要价值。 适用人群:适用于电气工程专业学生、电机控制领域的研究人员和技术人员。 使用场景及目标:帮助读者掌握异步电机矢量控制的技术细节,提高对复杂控制系统的设计能力,同时提供实践指导,便于进行相关实验和项目开发。 其他说明:文中提供了大量MATLAB/Simulink代码片段作为实例,有助于加深理解并应用于实际工作中。此外,还分享了一些调试技巧和注意事项,如坐标变换系数选择、积分抗饱和处理等。
内容概要:本文详细介绍了基于Simulink平台构建的黑鹰单旋翼直升机非线性动力学模型。该模型涵盖了主旋翼挥舞角动力学、尾桨控制、机身气动力等多个关键模块,并提供了完整的MATLAB源码。文章深入剖析了各个模块的工作原理,如挥舞角计算、气动耦合补偿、侧向力计算等,并分享了多个实用的仿真技巧和常见问题解决方案。此外,文中还提到了一些优化建议,如调整时间常数、改进积分方法以及处理代数环错误等。 适合人群:从事直升机仿真研究的技术人员、航空航天领域的研究人员、高校相关专业的师生。 使用场景及目标:帮助读者理解和掌握直升机非线性动力学建模的方法和技术,提高仿真的精度和效率。适用于教学、科研项目以及工业应用中的直升机性能评估和控制系统设计。 其他说明:附带的文献资料进一步补充了模型背后的理论依据,特别是关于旋翼失速特性和地面效应的研究成果。对于希望深入了解直升机空气动力学特性的读者来说,这些资料非常有价值。
python 基础:个人自用输入输出
电子仿真教程,从基础到精通,每个压缩包15篇教程,每篇教程5000字以上。
1、文件说明: Centos8操作系统textern-0.8-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf textern-0.8-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
内容概要:本文档《互联网大厂200道高频Node.js面试题.pdf》涵盖了Node.js技术栈的核心知识点及实际应用技巧。文档详细列举了200个常见面试问题及其解答,内容涵盖Node.js的基础概念、事件循环机制、错误处理、模块系统、Buffer和Stream的使用、进程与线程的区别及应用、异步操作的多种实现方式、集群模式下的性能优化、WebSocket的实现、大文件处理、全局对象的使用、Promise和async/await的优势、RESTful API的设计、环境变量管理、跨域请求处理、调试工具、内存管理和优化、Worker Threads的应用、负载均衡策略、测试框架的选择、静态文件服务、日志管理、HTTP/2的支持、数据库连接方式、微服务架构的设计、JWT认证、性能监控、文件上传与下载、Reactor模式的理解、定时任务的设置、多语言支持、文件预览、安全实践、Server-Sent Events(SSE)的使用、微前端集成、长轮询、GraphQL服务的构建、命令行工具的开发、单元测试编写、process对象的功能、优雅退出的方法、os模块的作用、CPU密集型任务的处理、加密解密、文件锁定、TCP服务创建、DNS解析、事件循环优化、数据压缩、内存缓存、自定义协议、分布式锁、工具函数、文件分片处理、HTTPS实现、请求超时控制、日志切割、URL参数解析、请求重试机制、V8模块的作用、文件内容搜索、断言模块的使用、动态路由、国际化域名处理、性能测量、文件同步、REPL交互环境、请求限
内容概要:本文详细介绍了3次B样条优化算法及其在Matlab中的具体实现。3次B样条作为一种广泛应用于计算机图形学和数据处理领域的曲线表示方法,因其良好的局部控制特性和光滑性而备受青睐。文中不仅阐述了3次B样条的基本理论,如基函数的递归计算公式,还给出了完整的Matlab代码实现,包括节点向量的生成、基函数的计算以及最终的曲线优化过程。此外,作者还分享了一些实用技巧,如避免常见的错误、提高计算效率的方法等。 适合人群:具有一定Matlab编程基础,对数值计算、数据拟合、计算机图形学等领域感兴趣的科研人员和技术开发者。 使用场景及目标:①需要对离散数据进行平滑处理的应用场合;②涉及轨迹规划、路径优化等问题的研究项目;③希望通过引入先进的数学工具改进现有算法性能的研发团队。 其他说明:文章提供的代码可以直接集成到现有的Matlab项目中,帮助用户快速实现3次B样条优化。同时,文中提到的一些优化建议和注意事项也有助于读者更好地理解和应用这一技术。
内容概要:本文详细介绍了如何使用COMSOL进行层合材料的超声波仿真,涵盖了从材料参数设置、几何建模、网格划分、物理场设置到求解器配置以及后处理的全过程。文中提供了大量MATLAB和Java代码片段,帮助用户快速构建并优化仿真模型。同时,作者分享了许多实践经验,如正确设置材料参数、采用合适的网格划分策略、调整求解器参数等,确保仿真结果更加贴近实际情况。 适合人群:从事复合材料研究的技术人员、超声波检测工程师、仿真软件使用者,尤其是有一定COMSOL使用基础的研究人员。 使用场景及目标:①掌握层合材料超声波仿真的完整流程;②提高仿真精度,解决常见的仿真误差问题;③通过实例学习如何优化模型设置,提升仿真效率。 其他说明:文章强调了材料参数设置、网格划分、求解器配置等方面的关键技术和注意事项,并提供了一些实用的代码示例和技巧,有助于读者更好地理解和应用这些知识点。
功能定位:这是一款专业的 Java 堆内存分析工具,主要用于: 诊断内存泄漏:通过分析堆转储文件(Heap Dump),定位未释放的无用对象。 优化内存使用:统计对象实例数量、内存占用及引用关系,提升应用性能。 支持场景:适用于开发调试、性能优化、故障排查(如 OOM 异常)等场景。
内容概要:本文详细介绍了四机两区系统中风储联合调频仿真的构建与优化。首先,通过频域建模将风电渗透率提高到25%,并通过虚拟惯性控制和储能下垂控制来增强系统的频率稳定性。文中展示了关键的MATLAB代码片段,解释了虚拟惯性控制和储能SOC管理的具体实现方式。此外,还讨论了频域建模的优势及其在仿真速度上的显著提升。最后,提供了仿真结果的数据分析,验证了所提方法的有效性。 适合人群:从事电力系统调频研究的技术人员、研究生以及相关领域的研究人员。 使用场景及目标:适用于希望深入了解风储联合调频机制的研究人员和技术开发者,旨在提供一种高效的仿真方法,以应对高风电渗透率带来的频率波动挑战。 其他说明:文中提及了一些实用的经验技巧,如解决Simulink频域模块的代数环错误的方法,以及参考文献的选择,有助于读者更好地理解和应用相关内容。
内容概要:本文详细介绍了CSR公司BlueCore3-Flash芯片,这款2004年推出的蓝牙单芯片解决方案集成了射频前端、基带处理和6Mbit闪存。文章首先回顾了其硬件架构,包括RF前端、ARM7 TDMI处理器、DSP协处理器及其存储管理。接着深入探讨了DSP协处理器对CVSD编码的优化以及RF部分的天线匹配和寄存器配置技巧。文中还提到了Flash分区管理和一些有趣的细节,如复活节彩蛋代码和通过GPIO模拟I2C控制EEPROM的方法。此外,作者分享了许多实用的经验教训,如Flash编程时序要求、寄存器配置陷阱等。最后强调了800页逆向分析报告的价值,特别是在射频校准方面的指导意义。 适合人群:从事蓝牙开发的工程师和技术爱好者,尤其是对早期蓝牙技术和硬件设计感兴趣的读者。 使用场景及目标:帮助读者深入了解BlueCore3-Flash芯片的工作原理和设计思路,掌握射频调试、DSP优化等关键技术,避免常见错误,提高开发效率。 其他说明:尽管BlueCore3-Flash已停产多年,但其设计理念和技术细节仍然值得借鉴,对于理解和优化现代蓝牙低能耗(BLE)系统具有重要参考价值。
FPS Game Template 2025 Unity FPS射击游戏插件模版项目源码C# Unitypackage 支持Unity2021.3.44或更高 描述 一款完整、有趣且令人享受的游戏,设计简单易懂,可以在最短的时间内构建更多样的游戏 这是一个完整的 fps 游戏模板,具有火箭发射器风格,基于新颖且有趣的游戏玩法制作 人们喜欢这种风格的游戏 使用这个令人惊叹的简单游戏模板可以非常轻松地使用此资产并创建新的环境 开始用火箭发射器风格的游戏制作新风格的 fps 游戏 特征: 简洁的设计 带有主菜单和敌人管理的完整模板 3 辆免费车辆和 2 辆免费火箭发射器模型 移动设备的自定义着色器 6 个预制级别 准备发布 流畅的游戏体验 从真实战争声音中剪切出的逼真音效 经过优化,可在任何平台上运行 WebGL 和移动版本
内容概要:本文详细介绍了锂离子电池恒流恒压(CC-CV)充电的Simulink仿真模型。首先解释了CC-CV充电的基本原理,即充电过程分为恒流充电和恒压充电两个阶段。接着阐述了Simulink仿真模型的具体构建方法,包括电源模块、充电控制模块、电池模型模块和测量与显示模块的设计。文中给出了恒流控制和恒压控制的关键代码示例,并讨论了状态机的实现逻辑,确保在特定条件下正确切换充电模式。此外,文章还探讨了仿真结果与理论的一致性,展示了电池电压和充电电流随时间的变化情况。最后,附上了详细的说明文档和参考文献,帮助读者深入了解模型的各个细节和技术背景。 适用人群:从事电池充电技术研发的工程师、研究人员以及对Simulink仿真感兴趣的高校学生。 使用场景及目标:适用于锂离子电池充电系统的开发和优化,旨在提高充电效率并防止过充,确保电池的安全性和使用寿命。通过学习本文,读者能够掌握CC-CV充电的工作机制,学会搭建和调试Simulink仿真模型。 其他说明:本文不仅提供理论知识,还包括实用的操作指南和代码示例,有助于读者将所学应用于实际项目中。