SQL查询指南(新手向)
2017-09-19 16:48 浏览次数:16
结构化查询语言(SQL)是数据挖掘分析行业不可或缺的一项技能,它既简单又强大,而本文是一些针对SQL新手的建议与指导
SQL处理和查询执行
为了提高SQL查询的性能,首先需要知道,运行查询时,内部会发生什么。
以下时查询执行的过程:
· 首先,将查询解析成“解析树”; 分析查询是否满足语法和语义要求。解析器将会创建一个输入查询的内部表示,然后将此输出传递给重写引擎。
· 然后,优化器的任务是为给定的查询,寻找最佳执行或查询计划。执行计划准确地定义了每个操作所使用的算法,以及如何协调操作的执行。
· 最后,为了找到最佳的执行计划,优化器会列举所有可能的执行计划,并确定每个计划的质量或成本,以便获取有关当前数据库状态的信息,最后选择最佳的执行计划。由于查询优化器可能不完善,因此数据库用户和管理员有时需要手动检查并调整优化器生成的计划,以便获得更好的性能。
现在你已经清楚了什么才是好的执行计划。
正如前面了解到的,计划的成本质量起着重要的作用。更具体地说,评估计划所需的磁盘I / O数量,计划的CPU花销以及数据库客户端的整体响应时间和总执行时间等因素至关重要。这就是时间复杂性的概念。后面还将继续了解。
接下来,执行所选择的查询计划,由系统的执行引擎进行评估,并返回查询结果。

编写SQL查询
需要进一步说明的是,垃圾回收原则(GIGO)原本就是表达在查询处理和执行之中:制定查询的人,同时也决定着SQL查询的性能。
这意味着在编写查询,有些事情可以同步去做。就像文章开始时介绍的,编写查询需要遵循两个标准:首先,编写的查询需要满足一定的标准,其次还应该应对查询中可以出现的性能问题。
总的来说,有四个分句和关键字,方便新手考虑性能问题:
· WHERE 分句
· INNER JOIN 和 LEFT JOIN 关键字
· HAVING 分句
虽然这种做法简单而天真,但对于一个初学者来说,这些方法却是一个很好的指引。这些地方也是你刚开始编写时,容易发生错误的地方,这些错误也很难发现。
同时,要想提升性能,使其变得有意义,就不能脱离上下文:在考虑SQL性能时,不能武断的认为上面的分句和关键字不好。使用WHERE 或 HAVING的分句也可能是很好的查询语句。
数据类型转换
应该使用最小的数据类型,因为小的数据类型更加有效。
当查询中需要进行数据类型转化,会增加执行时间,所以尽可能的避免数据类型转换的发生;
如果不能避免的话,需要谨慎的定义数据类型的转换。
基于集合和程序的方法进行查询
反向模型中隐含的事实是,建立查询时基于集合和程序的方法之间存在着不同。
· 查询的程序方法是一种非常类似于编程的方法:你告诉系统需要做些什么以及如何做。例如上一篇文章中的示例,通过执行一个函数然后调用另一个函数来查询数据库,或者使用包含循环、条件和用户定义函数(UDF)的逻辑方式来获得最终查询结果。你会发现通过这种方式,一直在请求一层一层中数据的子集。这种方法也经常被称为逐步或逐行查询。
· 另一种是基于集合的方法,只需指定需要执行的操作。使用这种方法要做的事情就是,指定你想通过查询获得的结果的条件和要求。在检索数据过程中,你不需要关注实现查询的内部机制:数据库引擎会决定最佳的执行查询的算法和逻辑。
由于 SQL 是基于集合的,所以这种方法比起程序方法更加有效,这也解释了为什么在某些情况下,SQL 可以比代码工作地更快。
基于集合的查询方法也是数据挖掘分析行业要求你必须掌握的技能!因为你需要熟练的在这两种方法之间进行切换。如果你发现自己的查询中存在程序查询,则应该考虑是否需要重写这部分。
从查询到执行计划
反向模式不是静止不变的。在你成为 SQL 开发者的过程中,避免查询反向模型和重写查询可能会是一个很艰难的任务。所以时常需要使用工具以一种更加结构化的方法来优化你的查询。
对性能的思考不仅需要更结构化的方法,还需要更深入的方法。
然而,这种结构化和深入的方法主要是基于查询计划的。查询计划首先被解析为“解析树”并且准确定义了每个操作使用什么算法以及如何协调操作过程。
查询优化
在优化查询时,很可能需要手动检查优化器生成的计划。在这种情况下,将需要通过查看查询计划来再次分析你的查询。
要掌握这样的查询计划,你需要使用一些数据库管理系统提供给你的工具。你可以使用以下的一些工具:
· 一些软件包功能工具可以生成查询计划的图形表示。
· 其它工具能够为你提供查询计划的文本描述。
请注意,如果你正在使用 PostgreSQL,则可以区分不同的 EXPLAIN,你只需获取描述,说明 planner 如何在不运行计划的情况下执行查询。同时 EXPLAIN ANALYZE 会执行查询,并返回给你一个评估查询计划与实际查询计划的分析报告。一般来说,实际执行计划会切实的执行这个计划,而评估执行计划可以在不执行查询的情况下,解决这个问题。在逻辑上,实际执行计划更为有用,因为它包含了执行查询时,实际发生的其它细节和统计信息。
时间复杂度和大O符号
通过前两篇文章,我们已经对查询计划有了一定了解。接下来,我们还可以借助计算复杂度理论,来进一步深入地挖掘和思考性能的提升。理论计算机科学这一领域聚焦于:根据难度来对计算问题进行分类。这些计算问题可以是算法问题,也可以是查询问题。
对于查询,我们可以不按照难度进行分类,而是按照运行查询并得到结果所需的时间来进行分类。这种方式也被称为按照时间复杂度进行分类。
使用大O符号,可以根据输入的增长速度来表示运行时间,因为输入可以任意大。大O符号不包括系数和低阶项,以便可以专注于查询运行时间的重要部分:增长率。使用这种方式时,会丢弃系数和低阶项,时间复杂度是逐渐描述出的,这意味着输入会变为无穷大。
在数据库语言中,复杂性衡量了查询运行时间的长短。
请注意,数据库的大小不仅随着表中存储数据的增加而增加,数据库中的索引也会影响数据库大小。
SQL调优
可以从以下方面衡量查询计划和时间复杂性,并进一步调优SQL查询:
· 用索引扫描替换不必要的大数据表的全表扫描;
· 确保表的连接顺序为最佳顺序;
· 确保以最佳方式使用索引;
· 将小数据表的全表扫描缓存起来。
本教程到此就结束了,算是浅尝辄止,但希望能对大家有所帮助.