首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

106-跟专家学习SQL优化-2

为什么生产系统平均执行时间60多秒, 测试执行只有0.55秒, 这个作者没有给出解释....我的这个优化方法,如果真如图1执行计划显示的那样, 预期优化后的执行时间也就十几毫秒. 但是再仔细想一想,事实应该并非如此....根据SQL实际执行时间60多秒这个事实, 图1执行计划中,驱动表E过滤后得到的真实结果集应该远大于估算的结果集1, 只有这样,才能对得上平均每次buffer gets 2605万(图2红框)这个数字....驱动表E返回的结果集大, 虽然我上面的优化方法在驱动表几十万记录的情况下也远比优化前效率高很多, 但是相对来说不如hash join更适合这个SQL,而且用了hash join, 隐式类型转换的问题也就无关紧要了...如果能够采集到60多秒执行情况下的sql monitor信息,就能够更清晰的看到执行计划中真实的结果集大小, 这种简单SQL的优化其实在1~2分钟内就能得出结论.

21020
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    数据库允许空值(null),往往是悲剧的开始(1分钟系列)

    =)查询,可能导致不符合预期的结果。 insert into user(name) values('wangwu'); 先构造一条id为NULL的数据,可以看到共有4条记录。...=1; 再次执行不等于查询。 你猜结果集有几条记录(共4条,不等于排除1条)? 答错了! 结果集只有2条记录,空值记录并未出现在结果集里。 画外音:第二次select的结果,意不意外?...此时,如果想到得到符合预期的结果集,必须加上一个or条件。 select * from user where id!=1 or id is null; 画外音:恶心不恶心,这个大坑你踩过没有?...union查询,又能够命中索引了,如上图所示: (1)type=ref,走非唯一索引; (2)rows=1,预估扫描1行; 画外音:第三行临时表的ALL,是两次结果集的合并。...=)的查询,不会将空值行(row)包含进来,此时的结果集往往是不符合预期的,此时往往要加上一个or条件,把空值(is null)结果包含进来; (3)or可能会导致全表扫描,此时可以优化为union查询

    72610

    必知必会——关于SQL中的NOT IN优化

    作为结果: ? 因为WHERE消除了条件不为TRUE的行,所以消除了房屋A。从SQL的角度来看,上面两个SELECT的结果是正确的。现在轮到您决定它们是否符合您的期望。 如果符合预期,那么一切都很好。...与SQL的理解不同,SQL意味着NULL为“也许是煤炭,天然气或其他,或者什么都不是”。 因此,就我的意图而言,NULL不可能是煤炭或木材,因此我希望IN不返回A,并且我希望NOT IN返回A。...那么,应该怎么做才能使NOT IN表现出预期的效果? 简单!我只需要用SQL更好地表达我想要的内容即可。 我可以将NOT IN更改为IN NOT TRUE: ?...>没有结果。 再次缺少A。同样,解决方案是: ? 现在我得到A。将其重写为IN IS NOT TRUE效果很好。 我可以改写为NOT EXISTS,但这是需要更多的编辑工作: ? 这也返回A。...要获得一百万个房屋,我只需要重复上一次的INSERT几次。现在我的搜索查询时间是: ? 反联接计划以更少的百分之二十的时间返回更多的行(如预期的那样,包括NULL)。

    4.9K40

    SQL之美- 通过SQL MONITOR解读并优化SQL

    本系列经典文章 之一:标量子查询优化 之二:OR展开与子查询优化案例详解。 之三:IN子查询返回结果集异常 今天是系列第四讲:通过SQL MONITOR来优化SQL 作者简介: ?...首先我们查询数据库中锁的信息,看到1752阻塞者是ACTIVE的,正在执行3wscxx88myd7t这个SQL。 ?...查询1752会话的状态,可以发现,1752会话执行ID为 3wscxx88myd7t 的SQL已经很长一段时间了。我们通过sql monitor来查看执行计划。这里需要特别注意红色方框里面的内容。...SQL执行的开始时间在15:48分,已经执行4760S还没有执行完,通过MODULE PROGRAM我们知道这个是前台打印发票,这个SQL正常情况下,应该在1S内出结果,执行这么久,明显是异常的。...这里看到,SQL已经按我们预期的提示走执行计划了。 下面看看SQL执行的性能。 ? 逻辑读下降到57 ,执行时间为Elapsed:00:00:00.06 The end ?

    1K40

    105-跟专家学习SQL优化-1

    根据上面执行计划显示, 其实oracle优化器把改写后的SQL做了查询转换,转换后的SQL应该是下面这个样子: 看到上面这个SQL, 估计很多人就能看出问题了, 这个sql的改写,只是结果上的等价,...这是因为这个SQL使用的一组变量, 返回的结果集为空(最后执行计划我标注1和2的地方), 因为t与m关联后结果集为空, n表的全表扫描不需要了(标注4); t与n关联后结果集为空, m表的全表扫描也不需要了...其实oracle从11g版本开始就可以对这个之前只能走filter的执行计划做查询转换, 使用的是一个叫unnest_disjunctive_subq的查询转换规则, 自动将sql转换成下面这个样子(下面其实是我的改写..."先分析一下表"(即收集表的统计信息) :这个可能是对SQL优化不太了解的人做调优的第一板斧,但明显这个SQL不适用; "子查询结果集小用in" : 这个说法要么不是搞oracle数据库的, 要么还在用...如果说一个sql可以不用改写, 通过hint或某些参数就能得到优化, 他这么说没问题, 这也是我在生产系统做优化的推荐做法.

    21710

    MySQL实战十八讲-为什么这些SQL语句逻辑相同,性能却差异巨大?

    接下来,我们使用 explain 命令,查看一下这条 SQL 语句的执行结果。...为了能够用上索引的快速定位能力,我们就要把 SQL 语句改成基于字段本身的范围查询。按照下面这个写法,优化器就能按照我们预期的,用上 t_modified 索引的快速定位能力了。...为什么有数据类型转换,就需要走全索引扫描? 先来看第一个问题,你可能会说,数据库里面类型这么多,这种数据类型转换规则更多,我记不住,应该怎么办呢?...这里有一个简单的方法,看 select “10” > 9 的结果: 1. 如果规则是“将字符串转成数字”,那么就是做数字比较,结果应该是 1; 2. ...这个回答,也是通常你搜索这个问题时会得到的答案。 但是你应该再追问一下,为什么字符集不同就用不上索引呢?

    40120

    正确评估SQL数据库性能,你必须知道的原理和方法!

    操作系统剩余内存过低有可能是SQL吃完了,所以不一定。那如何知道SQL使用的内存情况呢? 查询慢?查询慢,是否就是性能问题?...我个人认为是: 分为2种情况,第一是新系统运行与经验系统相差巨大,性能测试和压力测试不符合预期。第二种是正常运行系统发生与通常情况反映不一致状态,导致业务运行困难。...衡量性能问题的关键指标 响应时间(Response Time) 响应时间一般指的是一条SQL 语句执行后得出结果耗费的时间。...而执行SQL语句获得的响应时间是最为纯粹的反馈,也是能够得到准备信息的步骤。 在系统跟踪的话,可以用SQL profile 来跟踪响应的内容,分析语句的反馈时间,之后再来详细讲解。...理解瓶颈,知道发生了什么,然后做优化配置,调整执行慢的语句。 然后再反复,反复。 总结 调优是个系统工程,要有敏锐的触觉,有可能一条参数改变整个系统感受。所以深入理解原理和方法,才能得心应手。

    2.2K110

    MySQL深入学习第十八篇-为什么这些SQL语句逻辑相同,性能却差异巨大?

    接下来,我们使用 explain 命令,查看一下这条 SQL 语句的执行结果。如下 图2 所示为explain 的结果: ?...为了能够用上索引的快速定位能力,我们就要把 SQL 语句改成基于字段本身的范围查询。按照下面这个写法,优化器就能按照我们预期的,用上 t_modified 索引的快速定位能力了。...为什么有数据类型转换,就需要走全索引扫描? 先来看第一个问题,你可能会说,数据库里面类型这么多,这种数据类型转换规则更多,我记不住,应该怎么办呢?...这里有一个简单的方法,看 select “10” > 9 的结果: 1. 如果规则是“将字符串转成数字”,那么就是做数字比较,结果应该是 1; 2....这个回答,也是通常你搜索这个问题时会得到的答案。 但是你应该再追问一下,为什么字符集不同就用不上索引呢?

    51610

    【建议收藏】MySQL 三万字精华总结 —锁机制和性能调优(四)「建议收藏」

    返回结果中包括死锁相关事务的详细信息,如引发死锁的 SQL 语句,事务已经获得的锁,正在等待什么锁,以及被回滚的事务等。据此可以分析死锁产生的原因和改进措施。...---- 八、MySQL调优 ❝ 日常工作中你是怎么优化SQL的? SQL优化的一般步骤是什么,怎么看执行计划(explain),如何理解其中各个字段的含义?...如何写sql能够有效的使用到复合索引? 一条sql执行过长的时间,你如何优化,从哪些方面入手? 什么是最左前缀原则?什么是最左匹配原则?...通过 mysqldumpslow –help 查看操作帮助信息 得到返回记录集最多的10个SQL mysqldumpslow -s r -t 10 /var/lib/mysql/hostname-slow.log...得到访问次数最多的10个SQL mysqldumpslow -s c -t 10 /var/lib/mysql/hostname-slow.log 得到按照时间排序的前10条里面含有左连接的查询语句

    86630

    技术分享 | 某二手交易平台数据安全实践(建议对照自检)

    预估行:通过执行计划得到,不准确但可以作为参考。如果 SQL 是全表扫描,这个值跟实际情况可能相差很大。...Python 的 sqlparse 模块是 SQL 的解析库,但是在使用过程中遇到了很多问题,下面列举一些我遇到的问题: 连接查询:使用连接查询的场景,包含不限于 inner join、left join...UNION 查询:取并集操作也会对结果产生影响,可能无法获取预期内的表名列表。...子查询问题:不管是 SELECT 后面使用子查询,还是 FROM 后面使用子查询,还是 WHERE 后面使用子查询,都会对获取表名列表结果产生影响,可能无法获取预期内的表名列表。...如何获取导出语句的执行计划? 这部分工作倒是没什么特别复杂的,就说几个注意事项: MySQL 版本问题:5.6、5.7、8.0 的的执行计划结果不一样,需要注意适配。

    8510

    phalapi-进阶篇6(解决大量数据存储数据库分表分库拓展)

    ,如果有一天你的领导过来提了个需求,我需要一个数据分析系统来统计用户每天什么时间段最活跃.用户平均没人充值了多少钱啊,多少等级下用户冲钱最多啊,如果遇到这种问题你们会怎么办?...三分钟思考 我们先来看看我们会遇到什么样子的问题,数据量大积累当1000w+之后数据库执行sql基本没法看,大量的写入数据对数据库压力大 我们再来看看分表分库怎么解决这个问题,1000w+数据库的情况下...比如你是4表4库一共16张表,那每张表的数量就是1000w/16=62w也就是每张表只需要存储62w的数据就ok了,当写入数据的时候会根据ID的顺序均衡写入4库执行sql的压力也就分布到了4个数据库,...当我们使用where查询的时候操作如下: 如果where条件在前置表存在从前置表通过where获取结果集ID,通过ID分组到库和表,然后进行查询在拼接结果集统一返回 ##3....缺点 where查询字段必须预先添加到,前置表不然就必须遍历数据库数量 * 表数量才能得到想要的结果 where查询就算有前置表的情况下最坏的情况也需要遍历数据库数量 * 表数量才能得到想要的结果

    76990

    你不能不知道的Mybatis缓存机制!

    ,既然mybatis默认已经支持一级缓存,那么我执行两个一模一样的方法,肯定只需要查询一次数据库了,第二次就应该直接从缓存中取结果了 3)运行代码,如下图所示 ?...什么情况?骗人呢?打印了两条sql语句,这不还是查询了两次吗? 说实话,这个问题曾经困扰了我好几个小时,我在想,难道网上说的都有问题吗?是不是对于一级缓存,还专门有什么特殊配置呢?...那么以后再次查询时,缓存中总是找不到对应的key值,就会出现每次都重新执行sql语句,去数据库中查询的现象了 那么,我们便很容易就知道了,为什么会不支持一级缓存了。...同样是从数据库中查询得到结果,并将结果存放到缓存中 第二次查询 注意了,关键就在第二次查询 会继续判断从缓存中取对应key的值,这次我们可以取到key的value值,即它的查询结果,直接将这个结果集返回即可...sql语句只执行了一次,那么说明验证成功~ 小结 为什么会出现不开启事务时,一级缓存不生效;开启了事务,一级缓存生效?

    49721

    SQL 教程:如何编写更佳的查询

    除此之外,可以肯定地说,较新的技术也已经拥抱了SQL,比如Hive(一种用于查询和管理大数据集的类SQL查询语言接口)和Spark SQL(可用于执行SQL查询)。...应该尽可能避免使用DISTINCT子句;就像在其他示例中读过的那样,如果将此子句添加到查询中,执行时间只会增加。因此,考虑是否真的需要执行DISTINCT操作来获取要完成的结果,总是一个好主意。...另一种方法是基于集合的方法,这里我们只需指定要执行的操作。我们的任务包括为想从查询中得到的结果集指定条件或需求。...不过,这种结构化和深入的方法将主要是基于查询计划,而查询计划是首先被解析为“解析树”的查询结果,并且定义每个操作用什么算法以及操作的执行如何协调。...前者只得到一个说明计划器要如何执行查询的描述,但是不会执行查询;而后者会实际执行查询,并返回一个预期与实际查询计划的分析。

    1.7K40

    ​Mysql数据库查询好慢,除了索引,还能因为什么?

    索引页与磁盘页的关系 最后将得到的数据结果返回给客户端。 慢查询分析 如果上面的流程比较慢的话,我们可以通过开启profiling看到流程慢在哪。...比如从上面可以看出Sending data的耗时最大,这个是指执行器开始查询数据并将数据发送给客户端的耗时,因为我的这张表符合条件的数据有好几万条,所以这块耗时最大,也符合预期。...当然上面只是举了个例子,实际上,mysql执行sql时,不用索引或者用的索引不符合我们预期这件事经常发生,索引失效的场景有很多,比如用了不等号,隐式转换等,这个相信大家背八股文的时候也背过不少了,我也不再赘述...聊两个生产中容易遇到的问题吧。 索引不符合预期 实际开发中有些情况比较特殊,比如有些数据库表一开始数据量小,索引少,执行sql时,确实使用了符合你预期的索引。...正常情况下,客户端与server层如果只有一条连接,那么在执行sql查询之后,只能阻塞等待结果返回,如果有大量查询同时并发请求,那么后面的请求都需要等待前面的请求执行完成后,才能开始执行。

    55210

    Oracle 12.2 的连接消除特性

    很多人曾提出这样的问题,在一条SQL语句当中,from 子句所包含的表的顺序对SQL的执行计划或者SQL的性能有没有影响,从粗略的层面来讲,是没有影响的,但有一些特殊的情况可能会产生不一样的结果。...执行计划如下: ? 输出结果跟预期有些偏差, 优化器已经设法消除表的父 - 所以看起来像“单列主键”连接消除已经工作,但“多列”连接消除没有出现。 另一方面,这条语句并没有遵循通常写SQL的规则。...可见,基于多列主键的连接消除不起作用,可能必须按照列出from子句中的表的顺序菜可以产生预期的结果。...如果你想知道为什么传统方式和ANSI语法在进行连接时会选择相反的处理方向,记住,ANSI SQL首先被转换成一个等效的Oracle形式,在简单的情况下,前两个表形式第一个查询块然后每个表之后引入一个新的查询块...然后优化器优化内联查询,消除祖父级在父级和子级之间留下联接,最后才允许父级被删除。 但我们得到的结果如下: ?

    1.5K60

    故障分析 | MySQL 的隐式转换导致诡异现象的案例一则

    预期 test 表返回的记录都应该是这样的。...id a b 1 测试a 测试b 2 NULL 测试 我们看下三种数据库中,都执行如下语句,得到的是什么。...毕竟对产品来说,避免错误可能比表面上能执行更加重要,但就这个问题上,Oracle 和 SQL Server 可以说更胜一筹的。 2.3 问题分析 MySQL 为什么在这里会给出错误的结果?...3总结 我不知道这种设计是出于什么考虑,但这种"容错性"不可取,毕竟返回了错误的结果集。 当然,这个问题也和数据类型的使用有关,SQL 条件中 "a=0" 实际上是 "varchar=int"。...有可能是数据库设计的问题,比如,字段应该是 INT,但是定义成了 VARCHAR;还可能使开发人员的问题(SQL 条件右值应该用字符类型,例如 "0",但实际上用了 INT 数值类型的 0)。

    30440

    干货:MySQL 索引原理及慢查询优化

    并且兴致冲冲的找到了我,“这个SQL需要优化,给我把每个字段都加上索引” 我很惊讶,问道“为什么需要每个字段都加上索引?”...数据库也是一样,但显然要复杂许多,因为不仅面临着等值查询,还有范围查询(>、查询(like)、并集查询(or)等等。数据库应该选择怎么样的方式来应对所有的问题呢?...这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高 2.explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)...3.order by limit 形式的sql语句让排序的表优先查 4.了解业务方使用场景 5.加索引时参照建索引的几大原则 6.观察结果,不符合预期继续从0分析 几个慢查询案例 下面几个例子详细解释了如何分析和优化慢查询...所以我们第4步调差SQL的使用场景非常关键,我们只有知道这个业务场景,才能更好地辅助我们更好的分析和优化查询语句。

    47230

    通过cursor游标讲解,带你初步搞懂python操作mysql数据库

    有时候,我们执行一条查询语句的时候,往往会得到N条返回结果,执行sql语句取出这些返回结果的接口(起始点),就是游标。沿着这个游标,我们可以一次取出一行记录。...图示说明: 假设我们是在"游标功能开启"的状态下,执行这条SQL语句。此时蓝色方框中的结果集并不会马上打印到屏幕上,而是将这些结果存储起来,提供一个游标接口,图中的红色箭头。...如果不使用游标功能,直接使用select查询,会一次性将结果集打印到屏幕上,你无法针对结果集做第二次编程。...使用游标功能后,我们可以将得到的结果先保存起来,然后可以随意进行自己的编程,得到我们最终想要的结果集。...④ 结果分析 通过上述操作可以发现,这种游标功能可以帮助我们对SQL语句得到的结果集,进行二次开发,然后通过灵活的python语法,得到任何我们最终想要的结果集。

    11.2K85

    阿里的程序员也不过如此,竟被一个简单的 SQL 查询难住

    下面我以一个具体的例子来说明吧, 模拟其中的 SQL 查询场景....那么对应的 SQL 很自然的如下: 请忽略其中的数据, 我刚开始 mock 了 100W, 然后又重复导入了两遍, 因此数据有一些重复. 300W 数据, 最后查询出来也是 1.18 秒....你不妨思考一下, 如果你遇到这种场景, 应该怎么去排查? (分割线, 花 10 秒想想?) 我当时也是”一顿操作猛如虎”, 然并卵? 尝试了什么多种 sql 写法来完成这个操作....比如更换Join表的顺序(驱动表/被驱动表), 再比如用子查询. 最终, 还是没有结果. 但直接单表查询写 SQL 确能用上索引....注意一下 SQL 的执行顺序, 查询优化器工作流程, 以及其中的 Using join buffer (Block Nested Loop), 可以多看看 [MySQL 官方手册] (https://dev.mysql.com

    9110
    领券