Hash join is a type of join operation that uses a hash table to perform the join. There are three types of hash joins - optimal, onepass, and multipass. Optimal hash join performs the join entirely in memory, while onepass and multipass hash joins spill data to temporary storage due to insufficient memory. The size of the build table can impact the performance and memory requirements of the hash join, with smaller build tables generally requiring less memory but potentially more disk reads. The best build table depends on the relative sizes of the tables and available memory.
The document discusses CORBA and how it can be used with Java. CORBA provides a way to develop distributed applications and allows objects to communicate across networks or systems. Java is well-suited for building CORBA clients and servers. The document shows how to define an interface in IDL, generate Java stubs and skeletons, implement a server in Java that uses the interface, and register the server object.
Different algorithms can be used to implement joins in a database, including nested loop, block nested loop, indexed nested loop, merge, and hash joins. The optimal algorithm depends on factors like whether indexes are available on the joined attributes and the relative sizes and block distributions of the relations. Database tuning involves monitoring performance and adjusting aspects like indexes, queries, and design to improve response times and throughput.
This document discusses several Java technologies for building distributed applications: RMI, CORBA, JavaBeans, and Java IDL. It provides details on:
- RMI allows Java objects to invoke methods on remote objects residing in different JVMs. It uses stubs and skeletons as proxies.
- CORBA is a standard for building distributed applications and allows objects to interact across different platforms. It uses IDL for interface definitions.
- JavaBeans is a software component model for reusable GUI components. The document demonstrates how to create, configure, save and load JavaBeans.
This document discusses various types of joins in SQL including equi joins, outer joins, cartesian joins, and self joins. It also covers set operators like UNION, INTERSECT, and MINUS that combine the results of queries. Subqueries are discussed as a way to return data from multiple tables using a query within another query.
Le document présente un webinaire par Smile sur l'intégration des solutions WSO2 dans le domaine du e-commerce. Smile, en tant que leader européen de l'open source, met en avant ses 800 experts et ses solutions sur mesure pour optimiser les flux de commandes et les échanges d'informations dans le secteur. Différentes études de cas illustrent l'utilisation de WSO2 ESB dans des projets concrets, notamment des centrales d'achat et des marketplaces.
Ce document présente les Enterprise Java Beans (EJB), qui sont des composants serveurs facilitant la création d'applications distribuées pour les entreprises. Il décrit les différents types d'EJB, notamment les session beans, les message-driven beans, et leur gestion à travers le conteneur d'EJB. Le document aborde également des concepts avancés comme la persistance, la gestion des transactions, et l'utilisation d'interfaces locales et distantes.
本文檔介紹了在 Visual C++ 2005 上開發 C++ 程式和使用 Boost 庫的技巧,並探討了 C++ 語言的特性及其歷史。主要內容涵蓋了 Boost 庫的應用、字串處理及動態記憶體管理等主題,以幫助開發者提升程式碼的效率和安全性。作者邱銘彰提供了自己的專業背景,並分享了對於 C++ 和 Boost 的深刻見解。
Hash join is a type of join operation that uses a hash table to perform the join. There are three types of hash joins - optimal, onepass, and multipass. Optimal hash join performs the join entirely in memory, while onepass and multipass hash joins spill data to temporary storage due to insufficient memory. The size of the build table can impact the performance and memory requirements of the hash join, with smaller build tables generally requiring less memory but potentially more disk reads. The best build table depends on the relative sizes of the tables and available memory.
The document discusses CORBA and how it can be used with Java. CORBA provides a way to develop distributed applications and allows objects to communicate across networks or systems. Java is well-suited for building CORBA clients and servers. The document shows how to define an interface in IDL, generate Java stubs and skeletons, implement a server in Java that uses the interface, and register the server object.
Different algorithms can be used to implement joins in a database, including nested loop, block nested loop, indexed nested loop, merge, and hash joins. The optimal algorithm depends on factors like whether indexes are available on the joined attributes and the relative sizes and block distributions of the relations. Database tuning involves monitoring performance and adjusting aspects like indexes, queries, and design to improve response times and throughput.
This document discusses several Java technologies for building distributed applications: RMI, CORBA, JavaBeans, and Java IDL. It provides details on:
- RMI allows Java objects to invoke methods on remote objects residing in different JVMs. It uses stubs and skeletons as proxies.
- CORBA is a standard for building distributed applications and allows objects to interact across different platforms. It uses IDL for interface definitions.
- JavaBeans is a software component model for reusable GUI components. The document demonstrates how to create, configure, save and load JavaBeans.
This document discusses various types of joins in SQL including equi joins, outer joins, cartesian joins, and self joins. It also covers set operators like UNION, INTERSECT, and MINUS that combine the results of queries. Subqueries are discussed as a way to return data from multiple tables using a query within another query.
Le document présente un webinaire par Smile sur l'intégration des solutions WSO2 dans le domaine du e-commerce. Smile, en tant que leader européen de l'open source, met en avant ses 800 experts et ses solutions sur mesure pour optimiser les flux de commandes et les échanges d'informations dans le secteur. Différentes études de cas illustrent l'utilisation de WSO2 ESB dans des projets concrets, notamment des centrales d'achat et des marketplaces.
Ce document présente les Enterprise Java Beans (EJB), qui sont des composants serveurs facilitant la création d'applications distribuées pour les entreprises. Il décrit les différents types d'EJB, notamment les session beans, les message-driven beans, et leur gestion à travers le conteneur d'EJB. Le document aborde également des concepts avancés comme la persistance, la gestion des transactions, et l'utilisation d'interfaces locales et distantes.
本文檔介紹了在 Visual C++ 2005 上開發 C++ 程式和使用 Boost 庫的技巧,並探討了 C++ 語言的特性及其歷史。主要內容涵蓋了 Boost 庫的應用、字串處理及動態記憶體管理等主題,以幫助開發者提升程式碼的效率和安全性。作者邱銘彰提供了自己的專業背景,並分享了對於 C++ 和 Boost 的深刻見解。
Percona Live 2012PPT:mysql-security-privileges-and-user-managementmysqlops
The document discusses various aspects of MySQL security including:
- Privilege systems that control user access through granting of privileges to databases, tables, and other objects.
- User management features like creating and dropping users, setting passwords, and viewing granted privileges.
- Certain privileges like PROCESS, RELOAD, SHUTDOWN, and SUPER that provide powerful control over the database and should be granted carefully.
Percona Live 2012PPT: introduction-to-mysql-replicationmysqlops
This document provides an overview of MySQL replication including:
- Replication enables data from a master database to be replicated to one or more slave databases.
- Binary logs contain all writes and schema changes on the master which are used by slaves to replicate data.
- Setting up replication involves configuring the master to log binary logs, granting replication privileges, and configuring slaves to connect to the master and read binary logs from the specified position.
- Commands like START SLAVE are used to control replication and SHOW SLAVE STATUS displays replication status and lag.
Percona Live 2012PPT: MySQL Cluster And NDB Clustermysqlops
This document provides an introduction and overview of MySQL NDB Cluster. It discusses what NDB Cluster is, how MySQL uses NDB Cluster, good and bad use cases, and provides an example of query tuning. NDB Cluster is a high availability, distributed storage engine. It distributes and replicates data across nodes for high performance and reliability. MySQL can use NDB Cluster as a storage engine to provide scalability and high availability to MySQL applications.
Percona Live 2012PPT: MySQL Query optimizationmysqlops
The document discusses techniques for optimizing MySQL queries. It begins by explaining how to use EXPLAIN to view a query's execution plan and identify opportunities for improvement. Examples demonstrate how adding appropriate indexes can speed up queries by reducing the number of rows examined. The use of composite indexes, covering indexes, and index column order are also addressed. More advanced profiling techniques are presented to further analyze query performance beyond what EXPLAIN shows.
Pldc2012 innodb architecture and internalsmysqlops
Innodb uses a traditional OLTP architecture with row-based storage and row locking. Data is stored in tablespaces made up of segments and logs record changes in circular log files. The buffer pool caches data pages and uses an LRU algorithm to flush dirty pages. Multi-versioning allows transactions to read past versions of rows without locking while write operations require row locks. A variety of helper threads perform tasks like flushing data from the buffer pool to disk.
The document discusses eBay's data warehouse (EDW) and metadata management applications. It provides a history of eBay and overview of the EDW, which started in 2000 and is now the largest Teradata installation in the world. It describes key applications including a data flow diagram tool, data rationalization process, and JobTrack tool for monitoring ETL jobs. These applications help optimize the EDW through automated metadata analysis and management.
5. Oracle Join 简介 -Join 的类别 Join 类别 Inner Join and Outer Join Equi-Join and Non-Equi-Join Semi Join and Anti Join Self join 、 Cross Join… 能够识别 Join 和使用对应的 Join 很重要
6. Oracle Join 简介 -Examples Non-equi-Join and self Join Example SELECT a.ename,b.ename, a.hiredate,b.hiredate FROM scott.emp a,scott.emp b WHERE a.hiredate <= b.hiredate AND a.empno <> b.empno; …… 使用 Non-equi-join 要考虑清楚
7. Oracle Join 简介 -Examples Semi Join Example SELECT a.ename,a.hiredate FROM scott.emp a WHERE EXISTS (SELECT 1 FROM scott.emp b WHERE a.hiredate <= b.hiredate AND a.empno <> b.empno); Semi join 短路 Q : Semi join 最常见经典应用? A :找结果集是否存在数据
8. Oracle Join 简介 -Examples Anti Join Example SELECT a.ename,a.hiredate FROM scott.emp a WHERE NOT EXISTS (SELECT 1 FROM scott.emp b WHERE a.hiredate <= b.hiredate AND a.empno <> b.empno); Anti join 无短路 No matched results,so returned
9. 新旧 Join 语法 –理解 SQL86 中的“ +” Oracle 把我的 + 号吃了? Table a Table b right join SELECT a.ID,a.NAME,a.code, b.ID,b.NAME,b.code FROM a,b WHERE a.ID(+)=b.ID AND a.NAME(+)=b.NAME AND TO_NUMBER(a.code)=b.code; 注意复杂外连接的写法,不要丢掉 + 号
10. 新旧 Join 语法 –理解 SQL86 中的“ +” 加上 + 号后,执行计划为 SELECT a.ID,a.NAME,a.code, b.ID,b.NAME,b.code FROM a,b WHERE a.ID(+)=b.ID AND a.NAME(+)=b.NAME AND TO_NUMBER(a.code(+))=b.code; My god!so esay! My god!so easy!
11. 新旧 Join 语法 –理解 SQL86 中的“ +” “ +” 到底做了什么? If A and B are joined by multiple join conditions , then you must use the (+) operator in all of these conditions . If you do not, then Oracle will return only the rows resulting from a simple join , but without a warning or error to advise you that you do not have the results of an outer join. 理解文档中的 Join conditions 的含义很重要,文档并不详细。 可能会导致理解错误: 只要 right table 的列漏掉 + 就不是 外连接?
12. 新旧 Join 语法 –理解 SQL86 中的“ +” Table a Table b SELECT a.ID,a.NAME,b.ID,b.NAME FROM a,b WHERE a.ID(+)=b.ID AND a.ID IS NULL; SELECT a.ID,a.NAME,b.ID,b.NAME FROM a,b WHERE a.ID=b.ID AND a.ID IS NULL; SELECT a.ID,a.NAME,b.ID,b.NAME FROM a,b WHERE a.ID(+)=b.ID AND a.NAME=‘b’; SELECT a.ID,a.NAME,b.ID,b.NAME FROM a,b WHERE a.ID(+)=b.ID AND a.NAME=b.NAME; SELECT a.ID,a.NAME,b.ID,b.NAME FROM a,b WHERE a.ID(+)=b.ID AND a.ID(+) IS NULL; 先做外连接再过滤 内连接, join key 判断,无结果 内连接 ,“+” 无效 内连接 ,“+” 无效 一般外连接,无过滤 Table a Table b
14. 新旧 Join 语法 - 理解 SQL92 的 on 和 where ITPUB 问题:在两表查询时, on 和 where 到底没有没区别? YES OR NO ? Inner Join : SELECT a.ID,a.NAME,b.ID,b.NAME FROM a,b WHERE a.ID=b.ID AND a.NAME = b.NAME; SELECT a.ID,a.NAME,b.ID,b.NAME FROM a INNER JOIN b ON a.ID=b.ID AND a.NAME = b.NAME;
15. 新旧 Join 语法 - 理解 SQL92 的 on 和 where 对内连接来说,条件写在 on 里还是 where 里, 完全没有区别 执行计划 ---------------------------------------------------------- Plan hash value: 652036164 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 20 | 7 (15)| 00:00:01 | |* 1 | HASH JOIN | | 2 | 20 | 7 (15)| 00:00:01 | | 2 | TABLE ACCESS FULL| A | 2 | 10 | 3 (0)| 00:00:01 | |* 3 | TABLE ACCESS FULL| B | 3 | 15 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("A"."ID"="B"."ID" AND "A"."NAME"="B"."NAME") 3 - filter("B"."ID" IS NOT NULL)
16. 新旧 Join 语法 - 理解 SQL92 的 on 和 where 92 语法的 on 和 where 的区别,主要体现在 Outer Join 中 SELECT * FROM hr.departments dept RIGHT JOIN hr.locations loc ON dept.location_id=loc.location_id AND loc.city='Seattle';
17. 新旧 Join 语法 - 理解 SQL92 的 on 和 where 将前面的语句进行改写: SELECT * FROM hr.departments dept LEFT JOIN hr.locations loc ON dept.location_id=loc.location_id AND loc.city='Seattle';
18. 新旧 Join 语法 - 理解 SQL92 的 on 和 where on 和 where 混用的情况 (1) SELECT * FROM hr.departments dept LEFT JOIN hr.locations loc ON dept.location_id=loc.location_id AND loc.city='Seattle' WHERE loc.location_id>1500 ;
19. 新旧 Join 语法 - 理解 SQL92 的 on 和 where on 和 where 混用的情况 (2) SELECT * FROM hr.departments dept RIGHT JOIN hr.locations loc ON dept.location_id=loc.location_id AND loc.city='Seattle' WHERE loc.location_id>1500 ;
20. 新旧 Join 语法 - 理解 SQL92 的 on 和 where Conclusion: on is join condition where is filter condition 最终解决问题 寻找合适正确的语法支撑 分析对象的属性及相互关系 明确 SQL 的目标
22. 新旧 Join 语法 - 何时用新语法 +operator 的限制: --ORA-01719 OR 和 IN 都不可以和 + 连用 SELECT * FROM test1 a,test2 b WHERE a.ID=b.id(+) OR a.NAME IS NOT NULL; --OK SELECT * FROM test1 a,test2 b WHERE a.ID=b.id(+) AND a.NAME IS NOT NULL; --ORA-01799 + 不能与子查询连用 SELECT * FROM test1 a,test2 b WHERE a.ID=b.id(+) AND a.NAME(+) IN (SELECT c.NAME FROM test3 c) ; --OK SELECT * FROM test1 a,test2 b WHERE a.ID=b.id(+) AND a.NAME IN (SELECT c.NAME FROM test3 c);
23. 新旧 Join 语法 -Examples 用 +operator 改写 ANSI FULL JOIN SELECT a.ID,b.ID FROM a FULL JOIN b ON a.ID=b.ID; SELECT a.ID,b.ID FROM a,b WHERE a.ID=b.ID(+) UNION ALL SELECT a.ID,b.ID FROM a,b WHERE a.ID(+)=b.ID AND a.ID IS NULL; 分析: FULL JOIN 就是两个 left outer Join+ 去掉一边 left outer Join 中包含的 Inner Join 结果 My dear, 这个和 ANTI JOIN 好像啊
28. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 SELECT * FROM a WHERE a.object_name IN (SELECT b.object_name FROM b); SELECT * FROM a WHERE EXISTS (SELECT 1 FROM b WHERE a.object_name=b.object_name);
29. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 SELECT * FROM a WHERE a.object_name IN (SELECT b.object_name FROM b) OR a.object_id < (SELECT b.object_id FROM b WHERE b.object_id=80000); OR 限制
30. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 用 union 改写,逻辑读从 1594911 下降到 1091 SELECT * FROM a WHERE a.object_name IN (SELECT b.object_name FROM b) UNION SELECT * FROM a WHERE a.object_id < (SELECT b.object_id FROM b WHERE b.object_id=80000);
31. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 NOT IN 和 NOT EXISTS 要实现等价条件多 SELECT * FROM a WHERE a.object_name NOT IN (SELECT b.object_name FROM b); SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE a.object_name=b.object_name)
32. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 下面是 11g 下 NOT IN 计划 11g 之前的计划
33. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 --not anti join SELECT * FROM a WHERE a.object_name NOT IN (SELECT b.object_name FROM b WHERE b.object_name IS NOT NULL); --anti join SELECT * FROM a WHERE a.object_name IS NOT NULL AND a.object_name NOT IN (SELECT b.object_name FROM b WHERE b.object_name IS NOT NULL );
34. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 Anti Join 同样注意 OR 的问题
35. 常见 Join 问题和 Tuning- Semi Join 和 Anti Join 注意点 用 union 改写含有 or 的 anti join,filter 变为 anti join 和 union… 逻辑读减少,虽然 filter 的逻辑读也不大
36. 常见 Join 问题和 Tuning-Set 操作转换 Minus 一定条件下的改写: anti join 、外连接 SELECT a.object_id,a.object_name FROM a MINUS SELECT b.object_id,b.object_name FROM b; SELECT a.object_id,a.object_name FROM a WHERE NOT EXISTS ( SELECT 1 FROM b WHERE a.object_id=b.object_id AND a.object_name=b.object_name);
37. 常见 Join 问题和 Tuning-Set 操作转换 Intersect 一定条件下的改写: inner join 、 semi join SELECT a.object_id,a.object_name FROM a INTERSECT SELECT b.object_id,b.object_name FROM b; SELECT a.object_id,a.object_name FROM a WHERE EXISTS ( SELECT 1 FROM b WHERE a.object_id=b.object_id AND a.object_name=b.object_name);
38.
Editor's Notes
#8: Semi join 有短路功能 :意思是不全找,找到就 OK ,只要对应每行,查找到匹配的记录,则返回,然后继续下一次查找 Semi join 的一个实际使用,找结果集是否存在数据: select count(*) from dual where exists (select 1 from …); Semi join 也可以使用三大 join 算法, OK ,有 nested loops semi,hash joins semi and merge joins semin……. 以及对应的 hint 控制
#9: Anti Join 无短路 ,必须对应每行,与对子查询表全部查询一遍,然后无匹配,则返回此行记录,有匹配不返回 和 Semi join 一样,它也有三大算法以及对应的 hint 控制
#10: -- 检查执行计划,未发现 outer, 检查谓词未发现 + -- 语法级 SQL 转换 DROP TABLE a ; DROP TABLE b ; CREATE TABLE a (ID NUMBER,NAME VARCHAR2( 10 ), code VARCHAR2( 10 )); INSERT INTO a VALUES( 1 ,'a','00001'); INSERT INTO a VALUES( 2 ,'b','00002'); CREATE TABLE b (ID NUMBER,NAME VARCHAR2( 10 ), code NUMBER( 10 )); INSERT INTO b SELECT * FROM a ; INSERT INTO b VALUES( 3 ,'c', 3 ); COMMIT; SELECT * FROM a ; SELECT * FROM b ; dingjun123@ORADB> SELECT a.ID,a.NAME,a.code, 2 b.ID,b.NAME,b.code 3 FROM a,b 4 WHERE a.ID(+)=b.ID AND a.NAME(+)=b.NAME 5 AND TO_NUMBER(a.code)=b.code; 已选择 2 行。 已用时间 : 00: 00: 00.01 执行计划 ---------------------------------------------------------- Plan hash value: 652036164 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 60 | 7 (15)| 00:00:01 | |* 1 | HASH JOIN | | 1 | 60 | 7 (15)| 00:00:01 | | 2 | TABLE ACCESS FULL| A | 2 | 54 | 3 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL| B | 3 | 99 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access(&quot;A&quot;.&quot;ID&quot;=&quot;B&quot;.&quot;ID&quot; AND &quot;A&quot;.&quot;NAME&quot;=&quot;B&quot;.&quot;NAME&quot; AND &quot;B&quot;.&quot;CODE&quot;=TO_NUMBER(&quot;A&quot;.&quot;CODE&quot;)) Note ----- - dynamic sampling used for this statement (level=2) 统计信息 ---------------------------------------------------------- 7 recursive calls 0 db block gets 31 consistent gets 0 physical reads 0 redo size 775 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed dingjun123@ORADB> SELECT a.ID,a.NAME,a.code, 2 b.ID,b.NAME,b.code 3 FROM a,b 4 WHERE a.ID(+)=b.ID AND a.NAME(+)=b.NAME 5 AND TO_NUMBER(a.code(+))=b.code; 已选择 3 行。 已用时间 : 00: 00: 00.01 执行计划 ---------------------------------------------------------- Plan hash value: 843196925 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 3 | 180 | 7 (15)| 00:00:01 | |* 1 | HASH JOIN OUTER | | 3 | 180 | 7 (15)| 00:00:01 | | 2 | TABLE ACCESS FULL| B | 3 | 99 | 3 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL| A | 2 | 54 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access(&quot;A&quot;.&quot;ID&quot;(+)=&quot;B&quot;.&quot;ID&quot; AND &quot;A&quot;.&quot;NAME&quot;(+)=&quot;B&quot;.&quot;NAME&quot; AND &quot;B&quot;.&quot;CODE&quot;=TO_NUMBER(&quot;A&quot;.&quot;CODE&quot;(+)))
#13: -- 理解 +, Conclusion : + operator 的确是 outer join 语法 如果漏掉 righ table 端条件没有写 + ,则语义上是先做 outer join, 然后做 filter 如果 righ table 端其他列选择具体值或有对应列的 join ,但是漏掉 + ,则 Oracle 会将语句转为 inner join 如果 righ table 端条件是 IS NULL ,则是先外连接,再做 filter , 当然,如果是 IS NOT NULL ,则也转为内连接 Left table 的单列条件都是 filter INSERT INTO a VALUES(NULL,'c', 3 ); SELECT * FROM a ; SELECT * FROM b ; --1. 是先进行 id 的外连接,然后按 a.id is null 过滤,类似于 anti join ,找没有匹配到的 b 表记录 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .ID IS NULL; ALTER TABLE a DROP CONSTRAINTS uk_a ; ALTER TABLE b DROP CONSTRAINTS uk_b ; ALTER TABLE b MODIFY ID NULL; SELECT a .ID FROM a , b WHERE a .ID(+)= b .ID AND a .ID IS NULL; SELECT a .ID, a .NAME FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE a .ID= b .ID); -- 肯定不返回行,因为是内连接,而且是连接键 IS NULL SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID= b .ID AND a .ID IS NULL; -- 一般内连接, + 无效 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .NAME='b'; -- 一般内连接, + 无效 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .NAME= b .NAME; -- 外连接 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .ID(+) IS NULL; --DELETE FROM a WHERE ID=3; -- 列换为 name INSERT INTO a VALUES( 3 ,NULL, 3 ); INSERT INTO b VALUES( 4 ,'d', 4 ); SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .NAME(+) IS NULL; -- 过滤 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a RIGHT JOIN b ON a .ID= b .ID WHERE a .NAME IS NOT NULL; -- 非连接键值 , 下面两个也不同,第 1 个是先外连接后过滤 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .NAME IS NULL; SELECT a .ID, a .NAME, b .ID, b .NAME FROM a RIGHT JOIN b ON a .ID= b .ID WHERE a .NAME IS NULL; -- 第 2 个内连接 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID= b .ID AND a .NAME IS NULL; SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .ID IS NOT NULL; SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND a .NAME IS NOT NULL; --b.id>1 是过滤,先过滤再连接 SELECT a .ID, a .NAME, b .ID, b .NAME FROM a , b WHERE a .ID(+)= b .ID AND b .ID> 1 ;
#17: 老语法改写:只能是 where 条件 1.Where dept.location_id(+)=loc.location_id AND loc.city=‘Seattle’; -- 错误,因为有过滤 2. SELECT * FROM hr . departments dept , hr . locations loc WHERE dept . location_id (+)= loc . location_id AND loc . city =CASE WHEN ( dept . location_id (+) IS NOT NULL) THEN 'Seattle' ELSE 'Seattle' END; Loc.city= ‘Seattle’ 的前提是前面的 location_id 条件必须匹配或不匹配,这样外连接的条件就完整了 3. 也可以这样改写 SELECT * FROM hr . departments dept , hr . locations loc WHERE loc . location_id = decode ( loc . city ,'Seattle', dept . location_id (+));
#18: SELECT * FROM hr . departments dept LEFT JOIN hr . locations loc ON dept . location_id = loc . location_id AND loc . city ='Seattle'; SELECT * FROM hr . departments dept LEFT JOIN hr . locations loc ON dept . location_id = loc . location_id AND loc . city (+)='Seattle';
#23: drop TABLE test1 ; drop TABLE test2 ; drop TABLE test3 ; CREATE TABLE test1 AS SELECT 1 id, 'aa' NAME FROM dual UNION ALL SELECT 2 , 'bb' FROM dual UNION ALL SELECT 3 , 'cc' FROM dual ; CREATE TABLE test2 AS SELECT 1 id, 'aa' NAME FROM dual UNION ALL SELECT 4 , 'dd' FROM dual ; CREATE TABLE test3 AS SELECT 2 id, 'bb' NAME FROM dual UNION ALL SELECT 5 , 'ee' FROM dual ; SELECT * FROM test1 a , test2 b WHERE a .ID= b .id(+) OR a .NAME IS NOT NULL; SELECT * FROM test1 a , test2 b WHERE a .ID= b .id(+) AND a .NAME IS NOT NULL; SELECT * FROM test1 a , test2 b WHERE a .ID= b .id(+) AND a .NAME(+) IN (SELECT c .NAME FROM test3 c ); SELECT * FROM test1 a , test2 b WHERE a .ID= b .id(+) AND a .NAME IN (SELECT c .NAME FROM test3 c ); SELECT * FROM test1 a , test2 b , test3 c WHERE a .id = b .id(+) AND a .id = c .id(+); DROP TABLE test1 ; DROP TABLE test2 ; DROP TABLE test3 ; CREATE TABLE test1 AS SELECT 1 id, 'aa' NAME FROM dual UNION ALL SELECT 2 , 'bb' FROM dual ; CREATE TABLE test2 AS SELECT 1 id, 'aa' NAME FROM dual UNION ALL SELECT 4 , 'dd' FROM dual ; CREATE TABLE test3 AS SELECT 2 id, 'bb' NAME FROM dual UNION ALL SELECT 1 , 'aa' FROM dual UNION ALL SELECT 4 , 'dd' FROM dual UNION ALL SELECT 5 , 'ee' FROM dual ; --0ra-01417 一个表最多能外连接到一个表 -- 不知道谁才是基表 SELECT * FROM test1 a , test2 b , test3 c WHERE a .id(+) = b .id AND a .id(+) = c .id; -- 用中间结果集改写 SELECT * FROM (SELECT a .id aid , a .NAME aname , b .id bid , b .NAME bname FROM test1 a , test2 b WHERE a .id(+) = b .id) c , test3 d WHERE c . aid (+) = d .id; -- 基表最终是 test3 SELECT * FROM test1 a RIGHT JOIN test2 b ON a .ID = b .ID RIGHT JOIN test3 c ON a .ID = c .ID; -- 基表最终是 test2 SELECT * FROM test1 a RIGHT JOIN test3 b ON a .ID = b .ID RIGHT JOIN test2 c ON a .ID = c .ID;
#24: a.ID IS NULL 不能写成 a.ID(+) IS NULL, 习惯选择一个连接键判断,其他的也可以,比如 rowid DROP TABLE a ; DROP TABLE b ; CREATE TABLE a (ID NUMBER,NAME VARCHAR2( 10 )); CREATE TABLE b (ID NUMBER,NAME VARCHAR2( 10 )); INSERT INTO a VALUES( 1 ,'a'); INSERT INTO a VALUES( 2 ,'b'); INSERT INTO a VALUES( 3 ,'c'); INSERT INTO b VALUES( 1 ,'a'); INSERT INTO b VALUES( 2 ,'b'); INSERT INTO b VALUES( 4 ,'d'); COMMIT ; SELECT * FROM a ; SELECT * FROM b ; SELECT a .ID, b .ID FROM a FULL JOIN b ON a .ID= b .ID; -- 如果连接条件 1:1, 可以用 union SELECT a .ID, b .ID FROM a , b WHERE a .ID= b .ID(+) UNION SELECT a .ID, b .ID FROM a , b WHERE a .ID(+)= b .ID; -- 非 1:1 应该用 UNION ALL 并且第 2 个语句在 + 号处的列只选出 NULL 看到有些人经常问,把自己的一些体会简单举个例子,详细的东西还是需要自己慢慢体会的,比如 from a , b where a .id= b .id(+) and b .name='a' 这个 b . name 没有 + 号则相当于普通的内连接 ( 先外连接后过滤,这个准确点,比如 b .name is null 那么和普通内连接还是有所不同的 ) , -- 用连接键 is null 判断,不用考虑 null 问题,因为选择的是不配的值, rowid is null 也可以,他非连接键只能选择 NOT NULL 约束的 ?? 不对, 这个是过滤,所有没有匹配列都为 NULL INSERT INTO a VALUES( 1 ,'a'); SELECT a .ID, b .ID FROM a , b WHERE a .ID= b .ID(+) UNION ALL SELECT a .ID, b .ID FROM a , b WHERE a .ID(+)= b .ID AND a .ID IS NULL; -- 下面的是找以 id 连接在 b 中不在 a 中的数据,相当于 SELECT a .ID, b .ID FROM a , b WHERE a .ID(+)= b .ID AND a .ID IS NULL; ==> SELECT a .ID, b .ID FROM a RIGHT JOIN b ON a .ID= b .ID WHERE a .ID IS NULL; SELECT a .ID, b .ID FROM a , b WHERE a .ID(+)= b .ID AND a .ID(+) IS NULL; ===> SELECT a .ID, b .ID FROM a RIGHT JOIN b ON a .ID= b .ID AND a .ID IS NULL;
#25: 73993 * 3 + 295, 类似嵌套循环,效率很低,目标表必须做驱动表 全表更新 DROP TABLE a ; DROP TABLE b ; CREATE TABLE a AS SELECT * FROM all_objects ; CREATE TABLE b AS SELECT * FROM user_objects ; CREATE INDEX idx_a ON a ( object_id ); CREATE INDEX idx_b ON b ( object_id ); BEGIN dbms_stats . gather_table_stats ( ownname => USER, tabname => 'a',cascade => TRUE); dbms_stats . gather_table_stats ( ownname => USER, tabname => 'b',cascade => TRUE); END; SELECT COUNT(*) FROM a ; --73993 SELECT COUNT(*) FROM b ; --2301 UPDATE a SET a . object_name =(SELECT b . object_name FROM b WHERE a . object_id = b . object_id ); UPDATE a SET a . object_name =(SELECT b . object_name FROM b WHERE a . object_id = b . object_id ) WHERE EXISTS (SELECT 1 FROM b WHERE a . object_id = b . object_id ); MERGE INTO a USING b ON a . object_id = b . object_id WHEN MATCHED THEN UPDATE a . object_name = b . object_name ; ALTER TABLE b ADD CONSTRAINTS uk_b UNIQUE( object_id ); UPDATE (SELECT a . object_name aname , b . object_name bname FROM a , b WHERE a . object_id = b . object_id ) SET aname = bname ; SELECT 73993 * 3 + 295 FROM dual ;
#30: Exists 一样,只要 semi join 与 or 连用就走不了 semi,filter 效率经常低
#32: ALTER TABLE a MODIFY object_name NULL; ALTER TABLE b MODIFY object_name NULL; 对于 not exists 是 anti join,not in 主要看前后的都要有 not null 约束 SELECT * FROM a WHERE a . object_name NOT IN (SELECT b . object_name FROM b ); SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE a . object_name = b . object_name ) SELECT * FROM a WHERE a . object_name NOT IN (SELECT b . object_name FROM b WHERE b . object_name IS NOT NULL); -- 这个菜是 anti join SELECT * FROM a WHERE a . object_name IS NOT NULL AND a . object_name NOT IN (SELECT b . object_name FROM b WHERE b . object_name IS NOT NULL);
#36: ALTER TABLE a MODIFY object_name NULL; ALTER TABLE b MODIFY object_name NULL; SELECT * FROM a WHERE a . object_name IN (SELECT b . object_name FROM b ); SELECT * FROM a WHERE EXISTS (SELECT 1 FROM b WHERE a . object_name = b . object_name ) OR a . object_id < 80000 ; SELECT * FROM a WHERE a . object_name IN (SELECT b . object_name FROM b ) OR a . object_id < 80000 ; SELECT * FROM a WHERE a . object_name IN (SELECT b . object_name FROM b ) OR a . object_id < (SELECT b . object_id FROM b WHERE b . object_id = 80000 ); SELECT * FROM a WHERE a . object_name IN (SELECT b . object_name FROM b ) UNION SELECT * FROM a WHERE a . object_id < (SELECT b . object_id FROM b WHERE b . object_id = 80000 ); /*+precompute_subquery */ SELECT * FROM a WHERE a . object_name NOT IN (SELECT b . object_name FROM b ); SELECT /*+optimizer_features_enable('9.0.0')*/ * FROM a WHERE a . object_name NOT IN (SELECT b . object_name FROM b ); SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE a . object_name = b . object_name ) SELECT * FROM a WHERE a . object_name NOT IN (SELECT b . object_name FROM b WHERE b . object_name IS NOT NULL); -- 这个菜是 anti join SELECT * FROM a WHERE a . object_name IS NOT NULL AND a . object_name NOT IN (SELECT b . object_name FROM b WHERE b . object_name IS NOT NULL); SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE a . object_name = b . object_name ) OR a . object_id < 80000 ; SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE a . object_name = b . object_name ) UNION SELECT * FROM a WHERE a . object_id < 80000 ;