如何编写更好的SQL查询:终极指南-第二部分

上一篇文章中,我们学习了 SQL 查询是如何执行的以及在编写 SQL 查询语句时需要注意的地方。

下面,我进一步学习查询方法以及查询优化。

基于集合和程序的方法进行查询

反向模型中隐含的事实是,建立查询时基于集合和程序的方法之间存在着不同。

  • 查询的程序方法是一种非常类似于编程的方法:你告诉系统需要做些什么以及如何做。例如上一篇文章中的示例,通过执行一个函数然后调用另一个函数来查询数据库,或者使用包含循环、条件和用户定义函数(UDF)的逻辑方式来获得最终查询结果。你会发现通过这种方式,一直在请求一层一层中数据的子集。这种方法也经常被称为逐步或逐行查询。
  • 另一种是基于集合的方法,只需指定需要执行的操作。使用这种方法要做的事情就是,指定你想通过查询获得的结果的条件和要求。在检索数据过程中,你不需要关注实现查询的内部机制:数据库引擎会决定最佳的执行查询的算法和逻辑。

由于 SQL 是基于集合的,所以这种方法比起程序方法更加有效,这也解释了为什么在某些情况下,SQL 可以比代码工作地更快。

基于集合的查询方法也是数据挖掘分析行业要求你必须掌握的技能!因为你需要熟练的在这两种方法之间进行切换。如果你发现自己的查询中存在程序查询,则应该考虑是否需要重写这部分。

从查询到执行计划

反向模式不是静止不变的。在你成为 SQL 开发者的过程中,避免查询反向模型和重写查询可能会是一个很艰难的任务。所以时常需要使用工具以一种更加结构化的方法来优化你的查询。

对性能的思考不仅需要更结构化的方法,还需要更深入的方法。

然而,这种结构化和深入的方法主要是基于查询计划的。查询计划首先被解析为“解析树”并且准确定义了每个操作使用什么算法以及如何协调操作过程。

查询优化

在优化查询时,很可能需要手动检查优化器生成的计划。在这种情况下,将需要通过查看查询计划来再次分析你的查询。

要掌握这样的查询计划,你需要使用一些数据库管理系统提供给你的工具。你可以使用以下的一些工具:

  • 一些软件包功能工具可以生成查询计划的图形表示。
  • 其它工具能够为你提供查询计划的文本描述。

请注意,如果你正在使用 PostgreSQL,则可以区分不同的 EXPLAIN,你只需获取描述,说明 planner 如何在不运行计划的情况下执行查询。同时 EXPLAIN ANALYZE 会执行查询,并返回给你一个评估查询计划与实际查询计划的分析报告。一般来说,实际执行计划会切实的执行这个计划,而评估执行计划可以在不执行查询的情况下,解决这个问题。在逻辑上,实际执行计划更为有用,因为它包含了执行查询时,实际发生的其它细节和统计信息。

接下来你将了解 XPLAIN 和 ANALYZE 的更多信息,以及如何使用这两个命令来进一步了解你的查询计划和查询性能。要做到这一点,你需要开始使用两个表: one_million 和 half_million 来做一些示例。

你可以借助 EXPLAIN 来检索 one_million 表的当前信息:确保已将其放在运行查询的首要位置,在运行完成之后,会返回到查询计划中:

EXPLAINSELECT *FROM one_million;QUERY PLAN_________________________________________________Seq Scan on one_million(cost=0.00..18584.82 rows=1025082 width=36)(1 row)

在以上示例中,我们看到查询的 Cost 是0.00..18584.82 ,行数是1025082,列宽是36。

同时,也可以借助 ANALYZE 来更新统计信息  。

ANALYZE one_million;EXPLAINSELECT *FROM one_million;QUERY PLAN_________________________________________________Seq Scan on one_million(cost=0.00..18334.00 rows=1000000 width=37)(1 row)

除了 EXPLAIN 和 ANALYZE,你也可以借助 EXPLAIN ANALYZE 来检索实际执行时间:

EXPLAIN ANALYZESELECT *FROM one_million;QUERY PLAN___________________________________________________Seq Scan on one_million(cost=0.00..18334.00 rows=1000000 width=37)(actual time=0.015..1207.019 rows=1000000 loops=1)Total runtime: 2320.146 ms(2 rows)

使用 EXPLAIN ANALYZE 的缺点就是需要实际执行查询,这点值得注意!

到目前为止,我们看到的所有算法是顺序扫描或全表扫描:这是一种在数据库上进行扫描的方法,扫描的表的每一行都是以顺序(串行)的顺序进行读取,每一列都会检查是否符合条件。在性能方面,顺序扫描不是最佳的执行计划,因为需要扫描整个表。但是如果使用慢磁盘,顺序读取也会很快。

还有一些其它算法的示例:

EXPLAIN ANALYZESELECT *FROM one_million JOIN half_millionON (one_million.counter=half_million.counter);QUERY PLAN_____________________________________________________________Hash Join (cost=15417.00..68831.00 rows=500000 width=42)(actual time=1241.471..5912.553 rows=500000 loops=1)Hash Cond: (one_million.counter = half_million.counter)    -> Seq Scan on one_million    (cost=0.00..18334.00 rows=1000000 width=37)    (actual time=0.007..1254.027 rows=1000000 loops=1)        -> Hash (cost=7213.00..7213.00 rows=500000 width=5)    (actual time=1241.251..1241.251 rows=500000 loops=1)    Buckets: 4096 Batches: 16 Memory Usage: 770kB        -> Seq Scan on half_million    (cost=0.00..7213.00 rows=500000 width=5)(actual time=0.008..601.128 rows=500000 loops=1)Total runtime: 6468.337 ms

我们可以看到查询优化器选择了 Hash Join。请记住这个操作,因为我们需要使用这个来评估查询的时间复杂度。我们注意到了上面示例中没有 half_million.counter 索引,我们可以在下面示例中添加索引  :

CREATE INDEX ON half_million(counter);EXPLAIN ANALYZESELECT *FROM one_million JOIN half_millionON (one_million.counter=half_million.counter);QUERY PLAN______________________________________________________________Merge Join (cost=4.12..37650.65 rows=500000 width=42)(actual time=0.033..3272.940 rows=500000 loops=1)Merge Cond: (one_million.counter = half_million.counter)    -> Index Scan using one_million_counter_idx on one_million    (cost=0.00..32129.34 rows=1000000 width=37)    (actual time=0.011..694.466 rows=500001 loops=1)        -> Index Scan using half_million_counter_idx on half_million    (cost=0.00..14120.29 rows=500000 width=5)(actual time=0.010..683.674 rows=500000 loops=1)Total runtime: 3833.310 ms(5 rows)

通过创建索引,查询优化器已经决定了索引扫描时,如何查找 Merge join。

请注意,索引扫描和全表扫描(顺序扫描)之间的区别:后者(也称为“表扫描”)是通过扫描所有数据或索引所有页面来查找到适合的结果,而前者只扫描表中的每一行。

教程的第二部分内容,就介绍到这里。后续还会有《如何编写更好的SQL查询》系列的最后一篇文章,敬请期待。

原文链接:http://www.kdnuggets.com/2017/08/write-better-sql-queries-definitive-guide-part-2.html

转载请注明出自:葡萄城控件

时间: 2024-08-17 14:27:25

如何编写更好的SQL查询:终极指南-第二部分的相关文章

如何编写更好的SQL查询:终极指南-第三部分

本次我们学习<如何编写更好的SQL查询>系列的最后一篇文章. 时间复杂度和大O符号 通过前两篇文章,我们已经对查询计划有了一定了解.接下来,我们还可以借助计算复杂度理论,来进一步深入地挖掘和思考性能的提升.理论计算机科学这一领域聚焦于:根据难度来对计算问题进行分类.这些计算问题可以是算法问题,也可以是查询问题. 对于查询,我们可以不按照难度进行分类,而是按照运行查询并得到结果所需的时间来进行分类.这种方式也被称为按照时间复杂度进行分类. 使用大O符号,可以根据输入的增长速度来表示运行时间,因为

如何编写更好的SQL查询:终极指南-第一部分

结构化查询语言(SQL)是数据挖掘分析行业不可或缺的一项技能,总的来说,学习这个技能是比较容易的.对于SQL来说,编写查询语句只是第一步,确保查询语句高效并且适合于你的数据库操作工作,才是最重要的.这个教程将会提供给你一些步骤,来评估你的查询语句. 首先,应该了解学习SQL对于数据挖掘分析这个工作的重要性; 接下来,应该先学习SQL查询语句的处理和执行过程,以便可以更好的了解到,编写高质量的查询有多重要.具体说来就是,应该了解查询是如何被解析.重写.优化和最终评估的; 掌握了上面一点之后,你不仅

每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQL程序设计终极指南>志在打造PL/SQL领域最为系统.全面.实战.权威的著作,通过一系列非常突出的优势在大量的同类书中脱颖而出,成为该领域的标准读物. PL/SQL本身涉及的知识点浩瀚.庞杂,初学者根本无法依靠自身能力理清头绪,学习成本极高.本书对知识点进行了体系化的梳理,化繁杂为有序,突出重点,直指核

使用正规表达式编写更好的 SQL

Oracle Database 10g 中的正规表达式特性是一个用于处理文本数据的强大工具 Oracle Database 10g 的一个新特性大大提高了您搜索和处理字符数据的能力.这个特性就是正规表达式,是一种用来描述文本模式的表示方法.很久以来它已在许多编程语言和大量 UNIX 实用工具中出现过了. Oracle 的正规表达式的实施是以各种 SQL 函数和一个 WHERE 子句操作符的形式出现的.如果您不熟悉正规表达式,那么这篇文章可以让您了解一下这种新的极其强大然而表面上有点神秘的功能.已

SQL查询初学者指南读书笔记(四)where从句

CHAPTER6 Filtering Your Data 本章介绍WHERE从句. predicates Comparison,BETWEEN,IN, LIKE, and IS NULL. We'll cover theother two-Quantified and EXISTS-in Chapter 11, Subqueries. Comparison Equality and Inequality = ,<> Less Than and Greater Than <,> le

SQL查询初学者指南读书笔记(一)关系数据库和SQL介绍

PART I:Relational Databases and SQL Chapter2, Ensuring Your Database Structure IsSound. 数据库设计准则 什么是关系数据库 RDBMS (A Relational database management systems)关系数据库 Tables Tables are the mainstructures in the database. Each table always represents a single

SQL查询初学者指南读书笔记(二)创建SQL查询

PARTII: SQL Basics CHAPTER 4Creating a Simple Query 介绍一种如何创建SQL语句的技术--"Request/Translation/Clean Up/SQL" The SELECT operationin SQL can be broken down into three smaller operations, which we will referto as the SELECT statement,the SELECT expres

SQL查询初学者指南读书笔记(三)值表达式介绍

CHAPTER 5Getting More Than Simple Columns Intro Value  expression,itcontains column names, literal values, functions, orother value expressions The type of data TheSQL Standard defines seven general categories of types of data-character, nationalchar

SQL查询初学者指南读书笔记(五)集合操作与多表查询介绍

PART III:Thinking in Sets CHAPTER7 Thinking in Sets The three mostcommon set operations are as follows. Intersection Difference Union 在SQL中相应的关键词分别是 Intersection Except Union 实际数据库实现一般支持以下相应的数据库集合操作 INNER JOIN OUTER JOIN UNION JOIN 不过其区别是前者集合操作涉及表中所有