对韩峰著《SQL优化最佳实践》P7 案例的质疑
事先申明下,我的DB环境是Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production,如果与作者环境不同而导致结论差异则另当别论。
该案例做了一个id为varchar类型的两种查询对比,我模拟了一下。
我是这样建表的:
create table tb_varchar2id(
id varchar2(20) primary key,
name nvarchar2(20),
sal number(5,0)
) insert into tb_varchar2id
select rownum,dbms_random.string('*',dbms_random.value(6,20)),dbms_random.value(1000,30000) from dual
connect by level<=2000000
order by dbms_random.random
原作中是320万,我机器受限只能弄200万,这个差别不影响作者的思路和我的结论。
建表完提交后,开始第一个查询并观察其执行计划:
SQL> select * from tb_varchar2id where id>='';
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 3377844066 -----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1006K| 45M| 3602 (2)| 00:00:44 |
|* 1 | TABLE ACCESS FULL| TB_VARCHAR2ID | 1006K| 45M| 3602 (2)| 00:00:44 |
----------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("ID">='') Note
-----
- dynamic sampling used for this statement (level=2)
这里走的也是全表扫描,cost是3602,作者那边不同的是8927.
再看封闭范围的查询及执行计划:
SQL> select * from tb_varchar2id where id between '' and '';
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 1409398992 ---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 104K| 4773K| 399 (0)| 00:00:05 |
| 1 | TABLE ACCESS BY INDEX ROWID| TB_VARCHAR2ID | 104K| 4773K| 399 (0)| 00:00:05 |
|* 2 | INDEX RANGE SCAN | SYS_C0011453 | 104K| | 357 (0)| 00:00:05 |
--------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("ID">='' AND "ID"<='') Note
-----
- dynamic sampling used for this statement (level=2)
这把走的是索引范围扫描,cost是399,原著中是5(作者加了索引SYS_C0025295)。
就本例而言,换了查询方式后cost从3602降到399,似乎有了数量级的提升,而原著中8927到5,更是令人瞠目结舌!
很多看官看到这里都要作者所云以为开放(>=)区间查询要次于封闭区间(between)查询了,还以为作者给出了一条可行的优化之路。
但是,下面两条SQL执行结果是不一样的。
select * from tb_varchar2id where id>='1900000';
select * from tb_varchar2id where id between '1900000' and '2000000';
让我们看看它们的数量:
SQL> set autotrace off;
SQL> select count(*) from tb_varchar2id where id>=''; COUNT(*)
----------
999995 已用时间: 00: 00: 00.21
SQL> select count(*) from tb_varchar2id where id between '' and ''; COUNT(*)
----------
111113 已用时间: 00: 00: 00.00
前者是将近一百万条,后者是十一万条,数据量有一个数量级的差距,cost自然也有一个数量级的差距。
为什么会这样?因为id是varchar2类型,不是number类型,上面SQL在搞字符串比较呢。
就比如运行select * from tb_varchar2id where id>='1900000' and rownum<20;
SQL> select * from tb_varchar2id where id>='' and rownum<20; ID NAME SAL
-------------------- ---------------------------------------- ----------
1900000 YQJQLHKTYVLSZX 12533
1900001 SPLMMLXO 18104
1900002 TYGGIMJCSIWOWUX 6383
1900003 SYYYNRXSL 15890
1900004 GEGQAG 9448
1900005 SFGBZMMPOSEVMNEHQ 20339
1900006 OMQGZZWVEPRWIMTYK 13421
1900007 PWHATEOVY 11135
1900008 TLBRFDWDCEMXFYUXYH 15930
1900009 ZUIQECXIRQXBTO 15961
190001 WKEAMSE 25082 ID NAME SAL
-------------------- ---------------------------------------- ----------
1900010 CMPQCVUBXSMBCMI 17296
1900011 QDPNUNBDXBKV 17393
1900012 OYQBIBRADGE 12009
1900013 VIRWDAKEE 18760
1900014 NQJYHGKREUKGENWH 28990
1900015 IKUUFL 7899
1900016 ACQDSR 1195
1900017 NXIECMAVNE 4208 已选择19行。
连190001都混迹其中,这不应该是符合两个SQL意图的记录。
所以,这是不同SQL在比较性能,这有意义吗?
作者一开头就出这么一个让人费解的地方,或是有些细节没有明写在书里,引起读者疑惑,有点不应该。
--2020年1月31日--
对韩峰著《SQL优化最佳实践》P7 案例的质疑的更多相关文章
- sql优化最佳实践
1.选择最有效率的表连接顺序 首先要明白一点就是SQL 的语法顺序和执行顺序是不一致的 SQL的语法顺序: select [distinct] ....from ....[xxx join][o ...
- SQL Server - 最佳实践 - 参数嗅探问题 转。
文章来自:https://yq.aliyun.com/articles/61767 先说我的问题,最近某个存储过程,暂定名字:sp_a 总是执行超时,sp_a带有一个参数,暂定名为 para1 var ...
- 一触即发 App启动优化最佳实践
一触即发 App启动优化最佳实践 本文在 DiyCode 和 CSDN个人博客 同时首发,关注作者的 DiyCode帐号 或者 作者微博 可第一时间收到新文章推送. 文中的很多图都是Google性能优 ...
- Web前端优化最佳实践及工具集锦
Web前端优化最佳实践及工具集锦 发表于2013-09-23 19:47| 21315次阅读| 来源Googe & Yahoo| 118 条评论| 作者王果 编译 Web优化Google雅虎P ...
- paip.前端加载时间分析之道优化最佳实践
paip.前端加载时间分析之道优化最佳实践 1.另存为 ,查看文件尺寸..和图片. 2.view the 另存为的htm静态的文件单个的加载,看时间...可以排除编程语言的问题and 数据库.. ## ...
- 【读书笔记】读《高性能网站建设指南》及《高性能网站建设进阶指南:Web开发者性能优化最佳实践》
这两本书就一块儿搞了,大多数已经理解,简单做个标记.主要对自己不太了解的地方,做一些记录. 一.读<高性能网站建设指南> 0> 黄金性能法则:只有10%~20%的最终用户响应时间 ...
- [转] Web 前端优化最佳实践之 Mobile(iPhone) 篇
原文链接:http://dbanotes.net/web/best_practices_for_speeding_up_your_web_site_server_mobile.html Web 前端优 ...
- 经典的性能优化最佳实践 web性能权威指南 读书笔记
web性能权威指南 page 203 经典的性能优化最佳实践 无论什么网络,也不管所用网络协议是什么版本,所有应用都应该致力于消除或减 少不必要的网络延迟,将需要传输的数据压缩至最少.这两条标准是经典 ...
- 史上最全存储引擎、索引使用及SQL优化的实践
史上最全存储引擎.索引使用及SQL优化的实践 1 MySQL的体系结构概述 2. 存储引擎 2.1 存储引擎概述 2.2 各种存储引擎特性 2.2.1 InnoDB 2.2.2 MyISAM 3. 优 ...
随机推荐
- 18、Memento 备忘录模式
例如:用于记录快照(顺势状态).存盘 1.Memento Memento设计模式是一种软件设计模式,用于将对象回滚到其先前状态.它是行为设计模式的一部分,与算法和对象之间的职责分配有关. 行为模式描述 ...
- 浏览器编年史与UserAgent大乱斗
1993 世界上第一个支持显示图片的浏览器Mosaic诞生 为了区分浏览器是否能显示图片,UserAgent诞生了,Mosaic将自己标志为NCSA_Mosaic/2.0(windows 3.1) 1 ...
- “既生 ExecutorService, 何生 CompletionService?”
前言 在 我会手动创建线程,为什么要使用线程池? 中详细的介绍了 ExecutorService,可以将整块任务拆分做简单的并行处理: 在 不会用Java Future,我怀疑你泡茶没我快 中又详细的 ...
- Java学习书籍与社区
编码规范:<阿里巴巴Java开发手册> 技术架构:<大型网站技术架构核心原理与案例分析>---李智慧 Spring架构与设计原理解析:<Spring技术内幕深入解析Spr ...
- Jmeter逻辑控制器之If Controller的使用解析
一.If Controller概述 类似于编程语言中if语句,根据给定表达式的值决定是否执行该节点下的子节点,表达式的值 为true则执行,为false则不执行,默认使用javascript语法进行判 ...
- springboot~通过面向接口编程对控制反转IOC的理解
IOC,把控制反转到业务端,这句话没什么问题,在springboot框架里,对象的管理是通过spring ioc来实现的,而开发人员的开发原则里总是说"面向接口编程",而为什么要面 ...
- idea git拉取、合并、处理冲突、提交代码具体操作
早在两个月前我还在用eclipse开发,并且也发布的一些eclipse git的相关操作(操作都是本人亲自实践过的),但由于项目团队要求,开发工具统一用idea,实在不得已而为之切换了开发工具, 初次 ...
- 新手学习java路线
关于新手学习java的路线 笔者也是根据这个路线学习的,希望对你们有所帮助. 首先你要确定你是学习java 并且能够踏踏实实的走下去.一定要多学习,我也可以一直陪你走下去的. 笔者一年工作经验,科班毕 ...
- SpringMVC中前端Form表单提交后跳转不过去的问题
今天晚上打算谢谢Spring整合这个内容,写的差不多之后运行 出现了各种问题 逐一排查 首先有一个(MyEclipse10) 一: class path resource [spring-mvc.xm ...
- [CSP-S2019]格雷码 题解
CSP-S2 2019 D1T1 考场上第一遍读题的时候感觉不是很一眼……不是很符合D1T1的气质 之前完全没听说过格雷码是什么玩意,还是我太菜了 仔细读题后发现应该是有规律可循的 赛后据说有$O(1 ...