SQL优化--逻辑优化--非SPJ优化

1)GROUP BY分组转换(MySQL不支持)

①分组操作下移

GROUPBY 操作可能较大幅度减小关系元组的个数,如果能够对某个关系先进行分组操作,然后再进行表之间的连接,很可能提高连接效率。这种优化方式是把分组操作提前执行。下移的含义,是在查询树上,让分组操作尽量靠近叶子结点,使得分组操作的结点低于一些选择操作。

②分组操作上移

如果连接操作能够过滤掉大部分元组,则先进行连接后进行GROUPBY 操作,可能提高分组操作的效率。这种优化方式是把分组操作置后执行。上移的含义,和下移正好相反。

对于带有 GROUPBY 等操作的非 SPJ 格式的 SQL 语句,在本节之前提及的技术都适用,只是结合了 GROUPBY 操作的语义进行分组操作。因为 GROUPBY 操作下移或上移均不能保证重写后的查询效率一定更好,所以,要在查询优化器中采用基于代价的方式来估算某几种路径的优劣。

③MySQL的GROUP BY优化

MySQL 对于 GROUPBY 的处理,通常采用的方式是扫描整个表、创建一个临时表用以执行分组操作。查询执行计划中出现“ Usingtemporary” 字样表示 MySQL 采用了常规的处理方式。对于 GROUPBY 的优化,则尽量利用索引。

2)ORDER BY 优化

①排序消除( Order By Elimination , OBYE )

优化器在生成执行计划前,将语句中没有必要的排序操作消除(如利用索引),避免在执行计划中出现排序操作或由排序导致的操作(如在索引列上排序,可以利用索引消除排序操作)。

②排序下推( Sort push down )

把排序操作尽量下推到基表中,有序的基表进行连接后的结果符合排序的语义,这样能避免在最终的大的连接结果集上执行排序操作。

③MySQL的GROUP BY优化

利用索引的条件是:分组子句中的列对象源自同一个 btree 索引(不支持利用Hash 索引进行优化)的全部或前缀部分的部分有序的键(分组使用的索引列与索引建立的顺序不匹配则不能使用索引)。

主要的方式有 :

a)Loose IndexScan

直接用索引完成分组操作中对分组列的检索,不必考虑索引的全部键满足 WHERE 子句,只要有部分匹配 WHERE 中的列对象即可( loose ,利用索引中部分列为“松散”)。

b)Tight IndexScan

索引中的全部键与 WHERE 子句中的列对象匹配( tight ,利用索引中的全部列为“严密”)。

3)DISTINCT 优化

①DISTINCT 消除( Distinct Elimination )(MySQL支持)

如果表中存在主键、唯一约束、索引等,则可以消除查询语句中的 DISTINCT (这种优化方式,在语义优化中也涉及,本质上是语义优化研究的范畴)。

②DISTINCT 推入( Distinct Push Down )(MySQL不支持)

生成含 DISTINCT 的反半连接查询执行计划时,先进行反半连接再进行 DISTICT 操作;也许先执行 DISTICT 操作然后再执行反半连接,可能更优;这是利用连接语义上确保唯一功能特性进行 DISTINCT 的优化。

③DISTINCT 迁移( Distinct Placement )(MySQL不支持)

对连接操作的结果执行 DISTINCT ,可能把 DISTINCT 移到一个子查询中优先进行(有的书籍把这项技术称为“ DISTINCT 配置”)。

4)LIMIT优化

①MySQL的LIMIT优化

a)LIMIT对单表扫描的影响:如果索引扫描可用且花费低于全表扫描,则用索引扫描实现 LIMIT ( LIMIT 取很少量的行,否则优化器更倾向于使用全表扫描)。

b)LIMIT对排序的影响:如果 LIMIT 和 ORDERBY子句协同使用,当取到 LIMIT设定个数的有序元组数后,后续的排序操作将不再进行。

c)LIMIT对去重的影响:如果 LIMIT 和 DISTINCT子句协同使用,当取到 LIMIT设定个数的唯一的元组数后,后续的去重操作将不再进行。

d)LIMIT受分组的影响:如果 LIMIT 和 GROUPBY子句协同使用, GROUPBY 按索引有序计算每个组的总数的过程中,LIMIT 操作不必计数直到下一个分组开始计算。

e)LIMIT 0 :直接返回空结果集。

f)MySQL 支持对不带 HAVING 子句的 LIMIT 进行优化。

5)集合操作优化

①MySQL 的集合操作优化

a)MySQL 语法:

SELECT …

UNION [ALL |DISTINCT]SELECT …

[UNION [ALL |DISTINCT]SELECT …]

b)查询重写规则: OR 重写并集规则  ---MySQL 不支持。

c)需要引入代价估算的去评估重写后的代价,比较复杂。

6)总结

①常见的启发式规则

a)嵌套连接消除 : 如果都是内连接 , 则可以把表示嵌套关系的括号去掉。

A join (B join C) == A join B join C

b)选择操作下推。

c)投影操作下推 。

②常见的经验规则

a)在索引键上执行排序操作 , 通常利用索引的有序性按序读取数据而不进行排序。

b)选择率低于 10% 时 , 利用索引的效果通常比读表数据的效果好。

c)当表的数据量较少时 , 全表扫描可能优于其它方式 ( 如利用索引的方式 )。

摘自《数据库查询优化器的艺术》一书

时间: 2024-10-09 21:46:05

SQL优化--逻辑优化--非SPJ优化的相关文章

SQL优化--逻辑优化--视图重写与等价谓词重写

1)视图重写 视图的类型: a)用SPJ格式构造的视图,称为简单视图. CREATE VIEW v1 AS SELECT x, y, z FROM t; b)用非SPJ格式构造的视图(带有GROUPBY等操作),称为复杂视图. CREATE VIEW v2 AS SELECT x, y, z FROM t ORDER BY x; 视图重写: a)查询语句中出现视图对象 b)查询优化后,视图对象消失 c)消失的视图对象的查询语句, 融合到初始查询语句中 MySQL视图重写准则: a)MySQL支持

SQL优化--逻辑优化--子查询优化(MySQL)

1)子查询概念:当一个查询是另一个查询的子部分时,称之为子查询(查询语句中嵌套有查询语句). 子查询出现的位置有: a)目标列位置:子查询如果位于目标列,则只能是标量子查询,否则数据库可能返回类似"错误:  子查询必须只能返回一个字段"的提示. b)FROM子句位置:相关子查询出现在FROM子句中,数据库可能返回类似"在FROM子句中的子查询无法参考相同查询级别中的关系"的提示,所以相关子查询不能出现在FROM子句中:非相关子查询出现在FROM子句中,可上拉子查询到

【SQL server初级】数据库性能优化三:程序操作优化

数据库优化包含以下三部分,数据库自身的优化,数据库表优化,程序操作优化.此文为第三部分 数据库性能优化三:程序操作优化 概述:程序访问优化也可以认为是访问SQL语句的优化,一个好的SQL语句是可以减少非常多的程序性能的,下面列出常用错误习惯,并且提出相应的解决方案 一.操作符优化 1. IN.NOT IN 操作符 IN和EXISTS 性能有外表和内表区分的,但是在大数据量的表中推荐用EXISTS 代替IN . Not IN 不走索引的是绝对不能用的,可以用NOT EXISTS 代替 2. IS 

非凸优化问题

凸优化就是函数是凸函数,定义域也是凸集,不会有局部极小值问题:非凸优化就是在寻找最小值(或最大值)时会陷入局部极小值,这就是机器学习里某些算法经常遇到的问题. 记录今天学习到的matlab函数: 1. numel(A),求A的元素个数,即number of elements: 2. rem(A,a),求余,如果是向量,则返回的也是向量,每个元素对应原来除以a后的余数: 3. assert(expression,‘提示内容’),产生错误提示,当表达式expression不满足时,提示单引号内的内容

FPGA 设计如何进行面积优化(逻辑资源占用量优化)

FPGA面积优化 1 对于速度要求不是很高的情况下,我们可以把流水线设计成迭代的形式,从而重复利用FPGA功能相同的资源. 2 对于控制逻辑小于共享逻辑时,控制逻辑资源可以用来复用,例如FIR滤波器的实现过程中,乘法器是一个共享的资源,我们可以通过控制资源实现状态机,从而复用乘法器,当然这样也牺牲了面积. 3 对于具有类似计数单元的模块,可以采用全局的计数器,以减小面积.例如模块A需要256的循环计数,模块B需要1000的循环计数,那么我们就可以设计一个全局计数器,计数器位数为10,前八位供模块

Sql动态查询拼接字符串的优化

Sql动态查询拼接字符串的优化 最原始的 直接写:string sql="select * from TestTables where 1=1";... 这样的代码效率很低的,这样影响了数据库的索引引用如下所示:private void TestOneMethod()        {             string querySql = "select * from TestTables where 1=1";            if (hasOneCo

Sql Server随机抽取数据效率优化

Sql Server随机抽取数据效率优化2013-05-11 1 个评论 作者:菜光收藏 我要投稿Sql Server随机抽取数据效率优化 山人我最近遇到一件很纠结的事情,就是如何快速的从数据表里随机抽取一条数据. 我生成了一个简单的数据表,并且导入了500W条数据进行测试. 下图为第一次采用的SQL语句: Declare @d DatetimeSet @d=getdate()SELECT top 1[ActivityID] ,[CardNo] ,[Password] ,[State] ,[Cr

SQL优化工具 - SQL Server Profiler与数据库引擎优化顾问

最近项目做到几千个学生分别去人脸识别记录(目前约630000行)中查询最后一次记录,可想而知性能这块是个麻烦.于是乎,GET到了SQL Server Profiler和数据库引擎优化顾问这俩工SHEN具QI. 开始装逼... 首先来一条执行效率不怎么样的SQL语句 将SQL Server Profiler中的跟踪文件保存至本地 打开数据库优化引擎,选择工作负荷文件以及需要优化的数据库/表,点击开始分析 分析结束后会给你索引建议,执行操作→应用建议,将会自动生成SQL语句并执行,完成后再执行试试那

非凸优化的方法

关于非凸优化的方法, https://blog.csdn.net/kebu12345678/article/details/54926287 提到,可以把非凸优化转换为凸优化,通过修改一些条件. 非凸优化问题如何转化为凸优化问题的方法:1)修改目标函数,使之转化为凸函数2)抛弃一些约束条件,使新的可行域为凸集并且包含原可行域 而 https://blog.csdn.net/R1uNW1W/article/details/79000042 的论文提到了解决非凸优化问题的几种方法: 1.利用传统的凸