女主宣言

在SQL性能概述的第一部分中,我们研究了关系优化及其影响因素。在今天的文章中,我们将注意力转向查询分析以及SQL转换为可执行代码的方式。希望对大家在SQL性能优化方面有所帮助。

PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

在SQL性能概述的第一部分中,我们研究了关系优化及其影响因素。在今天的文章中,我们将注意力转向查询分析以及SQL转换为可执行代码的方式。

从上层看,优化过程包括四个步骤:

  1. 接收并验证SQL语句。

  2. 分析环境,优化满足SQL语句的方法。

  3. 创建机器可读的指令来执行优化的SQL。

  4. 执行这些指令或将它们存储起来以备将来执行。

需要做的第一件事是验证SQL是否写对了。这并不意味着它会做你希望它做的事情,只是它符合所需的语法。将对SQL进行分析和检查。如果遇到任何错误,进程将停止,你必须修改SQL,直到它正确为止。在验证SQL语法之后,下一步是检查语义,例如数据类型、引用约束、检查约束、视图和触发器。

这个过程的第二步是最有趣的。优化器如何决定如何执行可以按其方式发送的大量SQL语句?此查询分析步骤扫描SQL以确定其总体复杂性。SQL语句的表达式是决定优化器选择的访问路径的一个重要因素。查询的复杂性、谓词的数量和类型、函数的存在以及排序子句的存在都将进入优化器计算的估计成本中。

SQL语句越复杂,查询分析就必须做越多的工作来理解SQL语句。在查询分析期间,优化器分析SQL语句和数据库系统的各个方面,例如

  • 需要哪些数据库中的哪些表

  • 是否需要将任何视图分解为基础表

  • 是否需要表连接或子选择

  • 是否需要UNION、EXCEPT或INTERSECT

  • 可以使用哪些索引(如果有的话)

  • 必须满足多少谓词(WHERE子句)

  • 必须执行哪些函数

  • SQL是否使用OR或AND

  • DBMS如何处理SQL语句的每个组件

  • 为SQL语句中的表使用的数据缓存分配了多少内存

  • 如果查询需要排序,有多少内存可用于排序

换句话说,查询分析将SQL语句分解为必须执行的离散任务,以返回查询结果。

现代关系优化器是基于成本的,这意味着优化过程总是试图为每个查询制定一个降低总体成本的访问路径。为了实现这一点,优化器应用查询成本公式来评估和权衡每个潜在访问路径的多个因素:这些因素包括CPU成本、I/O操作、系统编目中的统计信息以及实际的SQL语句代码。

优化器可以重写查询,将其转换为等效的、但更容易编译和优化的版本。谓词下推和转换可能在此时发生。然后优化SQL。将审查和分析多条访问路径,以选择成本最低的选项。最后一步是创建实际的可执行代码。

1

访问路径

关系优化器有许多创建SQL访问路径的选项。在较高的层次上,有访问单个表中的数据的方法,也有组合两个表中的数据的方法。可以将这些方法组合成一系列访问方法,为SQL语句创建总体访问路径。

对于单表访问,可以使用扫描或索引检索数据。在优化器确定每个谓词可用的索引之后,它将决定是使用单个索引、多个索引还是根本不使用索引。

大家很容易说索引访问将优于扫描访问,但事实并非总是如此。优化器必须评估必须访问的数据量以及查询的性质。例如,如果你正在创建一个包含表中每一行的报告,那么使用索引可能比使用扫描读取所有数据要慢。

表扫描是最简单的数据访问形式。表扫描是通过读取表的每一行来执行的。根据DBMS的不同,可能存在另一种扫描类型,称为表空间扫描。表空间扫描读取表空间中的每个页面,表空间可能包含多个表。显然,表空间扫描将比表扫描运行得慢,因为可能会产生额外的I/O读取不适用的数据。

另一种扫描形式是分区扫描。如果DBMS能够确定要访问的数据存在于多分区表(或表空间)的某些分区中,那么它可以将扫描到的数据限制到适当的分区。分区扫描应该优于表扫描或表空间扫描,因为所需的I/O数量减少了。

通常,优化器会选择扫描数据,原因如下之一:

  • 使用索引无法满足查询,可能是因为没有索引可用、谓词与索引不匹配,或者谓词妨碍索引的使用。

  • 表中的行符合条件的百分比很高。在这种情况下,使用索引可能效率较低,因为无论如何都需要读取大多数数据行。

  • 具有匹配谓词的索引具有较低的集群比率,并且仅对少量数据有效。

  • 表太小,使用索引实际上是有害的。对于小表,向表访问添加索引访问可能会导致额外的I/O,而不是更少的I/O。

为了帮助扫描的性能,优化器可以调用数据预取。数据预取会导致DBMS在请求数据页之前,按顺序将数据页读入数据缓存。从本质上说,数据预取是一种读前机制——当数据扫描开始请求数据时,它已经存在于内存中。Prefetch对于扫描特别有用,但是对于任何类型的顺序数据访问都是实用的。你应该了解特定DBMS如何以及为什么预取数据。

2

索引存取

大多数的访问应该使用索引,这使我们可以选择扫描或索引访问。优化器必须首先发现是否存在索引。在编写SQL来访问列之前,不必定义索引—你可以查询数据库所知道的任何表的任何列。

此外,必须在SQL语句中的可索引谓词中引用至少一个索引列。DBMS不能为每个WHERE子句使用索引。您必须了解谓词可以使用哪些类型的索引来确保为数据库应用程序中的查询创建适当的索引。每个数据库管理系统都有一个不同的列表,其中列出了什么是可索引的,什么是不可索引的。此外,可索引的内容往往会随着每个DBMS的版本而变化。

优化器可以选择以许多不同的方式使用索引。第一个也是最简单的索引访问类型是直接索引查找。为了使DBMS能够执行直接索引查找,必须为索引中的每一列提供值。为了执行直接索引查找,DBMS将谓词中请求的值与索引根页中存储的值进行比较。基于这种比较,DBMS将把索引遍历到下一个页面集。如果存在中间的非叶页,则读取适当的非叶页,并比较该值以确定要访问哪个叶页。阅读适当的页;索引页包含指向符合条件的行实际数据的指针。基于页索引条目中的指针,DBMS读取适当的表数据页。

但是,假设SQL语句中没有提供索引的所有列。不能选择直接索引查找,因为DBMS不能匹配完整的索引键。相反,可以选择索引扫描。当一个索引扫描被调用时,索引的页被依次读取。

索引扫描有两种基本类型:匹配索引扫描和不匹配索引扫描。匹配的索引扫描有时称为绝对定位。匹配的索引扫描从索引的根页开始,以与直接索引查找相同的方式向下工作到叶页。但是,由于索引的完整键不可用,DBMS必须扫描索引的页,查找可用的值,直到检索到所有匹配的值。

要使用匹配的索引扫描,必须在索引键中指定高阶列;即索引DDL中指定的第一列。高阶列为DBMS从根页面到适当的叶页面遍历索引结构提供了起点。

请考虑在查询中不指定高阶列的后果。DBMS可以部署不匹配的索引扫描,有时称为相对定位。当由于索引键中的第一列未指定而无法确定起始点时,DBMS不能使用索引树结构。但是,它可以扫描索引页。不匹配的索引扫描从索引中的第一个页开始,然后应用可用的谓词顺序扫描后续的页。

不匹配的索引扫描可能比表或表空间扫描更有效,特别是如果必须访问的数据页是按集群顺序进行的。此外,请记住索引页(或块)包含的条目比表页多,因为索引“行”比表行短,从而使索引页I/O比扫描表页更有效。

总结

在本篇中,我们从较高的层次上研究了查询分析和访问路径公式,了解了查询分析的组件和单表访问方法。但还有更多的东西需要学习。在下一期文章中,我们将研究关系优化可以使用的多表访问方法。希望对大家在SQL性能优化方面有所帮助。

HULK一线技术杂谈

由360云平台团队打造的技术分享公众号,内容涉及云计算、数据库、大数据、监控、泛前端、自动化测试等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享

SQL性能第2篇:查询分析和访问路径制定相关推荐

  1. SQL性能第1篇:关系优化

    女主宣言 本文旨在让大家了解关系优化的相关内容,包括它的需求和需要考虑的重要问题.在下一部分中,我们将研究查询分析和优化器可以部署的一些方法,以制定SQL访问路径.希望对大家在SQL性能优化方面有所帮 ...

  2. mysql_性能优化一(慢查询分析)

    4.1 总论 MySQL 性能优化其实是个很大的课题,在优化上存在着一个调优金字塔的说法: 很明显从图上可以看出,越往上走,难度越来越高,收益却是越来越小的. 比如硬件和 OS 调优,需要对硬件和 O ...

  3. 数据仓库中的SQL性能优化 - Hive篇

    一个Hive查询生成多个map reduce job,一个map reduce job又有map,reduce,spill,shuffle,sort等多个阶段,所以针对hive查询的优化可以大致分为针 ...

  4. SQL性能优化第二篇之Mybatis如何能够执行多条SQL

    在第一篇基础上,数据库能够成功执行语句,但是放到Java代码中会报错有木有. 原来,mybatis在我们使用链接连接数据库时,需要我们手动在连接上加上代码: &allowMultiQuerie ...

  5. SQL性能优化第一篇之分页数据与Count数据一次性获取

    相信大部分人都会遇到:在数据库的数据量很大时,分页需要几秒钟才会全部完成:包括分页list的获取和count的获取.那我们完全可以将这两步放到一次sql去执行获取,减少一半的查询时间.这里get到sq ...

  6. 零基础学Python-爬虫-2、scrapy框架(测试案例篇·技术点在后面文章内讲解)【测试将一篇小说的所有访问路径与标题存储到一个文件下】

    本套课程正式进入Python爬虫阶段,具体章节根据实际发布决定,可点击[python爬虫]分类专栏进行倒序观看: [重点提示:请勿爬取有害他人或国家利益的内容,此课程虽可爬取互联网任意内容,但无任何收 ...

  7. 【华为云技术分享】上亿条数据,如何查询分析简单又高效?

    正值618大促,小张遇到了一个棘手的问题,需要在一周内将公司近1年电商部门的营收和线下门店经营数据进行联合分析. 这将产生哪些数据难题呢? 数据孤岛:电商部门的数据存在数仓A.门店经营收入数据存在数仓 ...

  8. 【MySQL数据库 | 第十九篇】SQL性能分析工具

    目录 前言: SQL执行频率: 慢查询日志: profile: profile各个指令: 总结: 前言: 本篇我们将为大家讲解SQL性能的分析工具,而只有熟练的掌握了性能分析的工具,才可以更好的对SQ ...

  9. MySQL 进阶 索引 -- SQL性能分析(SQL执行频率:查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次、慢查询日志、 profile详情、explain)

    文章目录 1. SQL性能分析 1.1 SQL执行频率(可以查看当前数据库SQL的访问频次) 1.2 慢查询日志(可以记录用时较长的SQL) 1.2.1 开启慢查询日志 1.2.2 慢查询日志测试 1 ...

最新文章

  1. Python处理XML文件
  2. 结构光|一文详解相移步长的选择问题
  3. 虚拟内存,虚拟地址空间,用户空间,内核空间
  4. PAT甲级1017 Queueing at Bank:[C++题解]字符串、结构体、最小堆
  5. Linux编译动态链接库
  6. opencv用haartraining训练出现的一些问题
  7. hdu 4857 Little Devil I
  8. 语音跟踪:信号分解、锁相、鸡尾酒会效应、基于PR的信号分离
  9. java new string作用_java中直接new String对象?
  10. 《开源硬件创客——15个酷应用玩转树莓派》——第1章 初识树莓派
  11. 面试题:左旋转字符串
  12. 李洪强和你一起学习前端之(9)规避脱标,CSS可见性,滑动门案例
  13. WebForm中 页面传参的总结
  14. 山东工商学院 计算机科学与技术,实验中心-山东工商学院计算机科学与技术学院...
  15. tecplot教程发布
  16. UCOS操作系统——信号量实验(十)
  17. 博科300 java配置,博科300 光纤交换机如何设置为SSH登录?
  18. 【Java】异步回调转为同步返回
  19. 经典数据挖掘算法(介绍了包括18大数据挖掘在内的多种经典数据挖掘算法)
  20. 低功耗设计及其UPF实现第四节(最后一节)

热门文章

  1. javascript焦点图
  2. 诗和远方:无题(五十一)
  3. foo( a )JAVA面试题_Java相关面试题总结+答案(五)
  4. gdal数据类型_科学网-gdal数据类型的代码的核心定义文件-林清莹的博文
  5. Git--版本管理的使用及理解
  6. Linux下如何设置和查看环境变量
  7. 是什么还让你停留在 iOS 平台?是这些理由吗
  8. HDU 5400 Arithmetic Sequence
  9. 《深入理解Android:卷III A》一一第3章 深入理解AudioService
  10. 在sphinx中处理使用特殊字符时所引起错误的办法