问题描述
嗨,
请看下面的两个SQL语句,一个我使用RANK,另一个我使用ROW_NUMBER。
请注意,在我们使用秩的情况下,基数估计是正确的,而在ROW_NUMBER的情况下,基数估计将更改为1。
我做错什么了吗?
问候!!
请看下面的两个SQL语句,一个我使用RANK,另一个我使用ROW_NUMBER。
请注意,在我们使用秩的情况下,基数估计是正确的,而在ROW_NUMBER的情况下,基数估计将更改为1。
我做错什么了吗?
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 0 PL/SQL Release 12.1.0.2.0 - Production 0 CORE 12.1.0.2.0 Production 0 TNS for Linux: Version 12.1.0.2.0 - Production 0 NLSRTL Version 12.1.0.2.0 - Production 0 SELECT a.renamed_1_id , a.renamed_2 , a.name , a.statUS FROM (SELECT renamed_1_ID , renamed_2 , NAME , STATUS , RANK () OVER ( PARTITION BY NAME ORDER BY DECODE (STATUS , 'ACTIVE', 1 , 'SUSPENDED', 2 , 3) , last_update_time DESC) RN FROM nme_renamed_1) a WHERE a.RN = 1; Plan SELECT STATEMENT ALL_ROWSCost: 4 Bytes: 7,200 Cardinality: 72 3 VIEW <>. Cost: 4 Bytes: 7,200 Cardinality: 72 2 WINDOW SORT PUSHED RANK Cost: 4 Bytes: 3,960 Cardinality: 72 1 TABLE ACCESS FULL TABLE < >.nme_renamed_1 Cost: 3 Bytes: 3,960 Cardinality: 72 SELECT a.renamed_1_ID , a.renamed_2 , a.NAME , a.STATUS FROM (SELECT renamed_1_ID , renamed_2 , NAME , STATUS , ROW_NUMBER () OVER ( PARTITION BY NAME ORDER BY DECODE (STATUS , 'ACTIVE', 1 , 'SUSPENDED', 2 , 3) , last_update_time DESC) RN FROM nme_renamed_1) a WHERE a.RN = 1; Plan SELECT STATEMENT ALL_ROWSCost: 4 Bytes: 100 Cardinality: 1 3 VIEW < >. Cost: 4 Bytes: 100 Cardinality: 1 2 WINDOW SORT PUSHED RANK Cost: 4 Bytes: 3,960 Cardinality: 72 1 TABLE ACCESS FULL TABLE < >.nme_renamed_1 Cost: 3 Bytes: 3,960 Cardinality: 72 复制
问候!!
专家解答
Row_number() 为每一行分配一个新值。因此,您可以保证只有一行的值为1。
Rank() 为领带分配相同的值。所以你可以有rank = 1的任意数量的行:
您使用row_number() 的查询只能返回一行。所以这 (1) 的基数估计是正确的。
当使用rank() 时,您可以返回1-72行之间的任何位置 (假设第2步的估计是正确的)。优化器在这里遇到最坏的情况:
Rank() 为领带分配相同的值。所以你可以有rank = 1的任意数量的行:
create table t as select 1 x from dual connect by level <= 5; exec dbms_stats.gather_table_stats(user, 't'); select row_number() over (order by x) rn , rank() over (order by x) rk from t; RN RK 1 1 2 1 3 1 4 1 5 1复制
您使用row_number() 的查询只能返回一行。所以这 (1) 的基数估计是正确的。
当使用rank() 时,您可以返回1-72行之间的任何位置 (假设第2步的估计是正确的)。优化器在这里遇到最坏的情况:
set serveroutput off with rns as ( select row_number() over (order by x) rn , rank() over (order by x) rk from t ) select * from rns where rk = 1; select * from table(dbms_xplan.display_cursor(null, null, 'BASIC +ROWS')); PLAN_TABLE_OUTPUT EXPLAINED SQL STATEMENT: ------------------------ with rns as ( select row_number() over (order by x) rn , rank() over (order by x) rk from t ) select * from rns where rk = 1 Plan hash value: 2764225767 ------------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1 | VIEW | | 5 | | 2 | WINDOW SORT PUSHED RANK| | 5 | | 3 | TABLE ACCESS FULL | T | 5 | ------------------------------------------------- with rns as ( select row_number() over (order by x) rn , rank() over (order by x) rk from t ) select * from rns where rn = 1; select * from table(dbms_xplan.display_cursor(null, null, 'BASIC +ROWS')); PLAN_TABLE_OUTPUT EXPLAINED SQL STATEMENT: ------------------------ with rns as ( select row_number() over (order by x) rn , rank() over (order by x) rk from t ) select * from rns where rn = 1 Plan hash value: 2764225767 ------------------------------------------------- | Id | Operation | Name | Rows | ------------------------------------------------- | 0 | SELECT STATEMENT | | | | 1 | VIEW | | 1 | | 2 | WINDOW SORT PUSHED RANK| | 5 | | 3 | TABLE ACCESS FULL | T | 5 | -------------------------------------------------复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
603次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
588次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
496次阅读
2025-04-08 09:12:48
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
479次阅读
2025-04-20 10:07:02
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
464次阅读
2025-04-22 00:20:37
Oracle 19c RAC更换IP实战,运维必看!
szrsu
440次阅读
2025-04-08 23:57:08
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
438次阅读
2025-04-22 00:13:51
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
429次阅读
2025-04-17 17:02:24
火焰图--分析复杂SQL执行计划的利器
听见风的声音
371次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
361次阅读
2025-04-15 14:48:05