当前位置:首页 » 编程语言 » sql优化试题
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

sql优化试题

发布时间: 2022-10-04 06:16:23

sql优化(二)

SQL优化一: sql优化(一)

上片文章已经详细介绍了explain各个字段的含义,以及什么情况应该建立索引,什么情况不需要建立索引以及sql语句性能的判断依据,接下来我介绍下如何合理的建立索引。

sql语句:select id,author_id from article where category_id = 1 and comments>1 order by views desc limit 1;

分析:首先我们根据where后面的条件建立符合索引,然后根据order by后面的字段建立索引,因此建立索引idx_article_ccv,即以(category_id,comments,views)数据列建立复合索引,但由于comments是一个范围,按照BTree索引的原理,先排序category_id,如果遇到相同的category_id则再排序comments,如果遇到相同的comments则再排序views,又因为comments字段在复合索引里处于中间位置,而comments>1是一个条件(是一个范围值),在复合索引的一个范围值的数据列后面的索引全部失效,mysql无法利用索引再对后面的views部分进行检索,也就是说views无法按照索引排序,所以explain下此sql语句,type为range,extra使用的是Using filesort,这是比较糟糕的。所以我们放弃comments这个范围字段,建立索引idx_article_cv,即以(category_id,views)数据列建立复合索引,explain 此sql,type变成了ref,extra的using filesort也变成了using index,这就变得好多了。

索引:idx_article_cv,即以(category_id,views)数据列建立复合索引

前段时间做了一个销售精细化项目,是公司crm项目的一个大模块,大致就是为销售人员制定指标,实现销售目标从区域到团到业务员到客户,实时跟踪业务员所负责客户的下单量的情况。这就存在许多关联关系,区域-团,团-业务员,业务员-客户,这使得sql常常需要关联多张表。

sql语句:SELECT

tu.fuserid,

tu.faccount,

tu.fphone,

tu.fcertificationtype,

tu.fcertificatename,

tu.fkeyarea,

tu.fkeyareatext,

DATE_FORMAT(tcr.fupdatetime,'%Y-%m-%d %H:%i:%s') as fupdatetime,

tag.forggroupid,

tag.forggroupname,

tug.forguserid,

tug.fusername,

tug.fuserphone,

tag.fcitycode

FROM t_finedt_user AS tu

LEFT JOIN t_finedt_customer_relation AS tcr

ON tu.fuserid = tcr.fuserid

LEFT JOIN t_finedt_usergroup AS tug

ON tcr.forguserid = tug.forguserid

and tcr.forggroupid = tug.forggroupid

LEFT JOIN t_finedt_areagroup AS tag

ON tug.forggroupid = tag.forggroupid

where tu.fkeyarea=? and tu.fuserid=? and tug.forggroupid = ?

分析:上面的sql是左连接,左边的表一定是全表查询,所以要建立右边表对应关联字段的索引,在表t_finedt_user上建立tu_fuserid_fkeyarea索引,即以(fuserid,fkeyarea)字段建立索引,在表t_finedt_customer_relation 上建立tcr_forguserid_forggroupid索引,即以(forguserid,forggroupid)字段建立索引,在表t_finedt_usergroup 上建立tug_forguserid_forggroupid索引,即以(forguserid,forggroupid)字段建立索引,在表t_finedt_areagroup上建立tag_forggroupid索引,即以(forggroupid)字段建立索引。建立索引后,sql查询速度明显快了很多

索引:tcr_forguserid_forggroupid,tu_fuserid_fkeyarea,tug_forguserid_forggroupid,tag_forggroupid

1、尽可能减少join语句中的NestedLoop的循环次数,永远用小结果集驱动大结果集

2、优先优化NestedLoop的内层循环

3、保证join语句总被驱动表上的join字段已经被索引

4、当无法保证被驱动表join条件字段被索引,且内存资源充足的前提下,不要太吝啬joinBuffer的设置

1、全值匹配我最爱

2、最佳左前缀原则——如果索引了多列,要遵守最左前缀原则,指的是查询从索引的最左前列开始并且不跳过索引中的列

3、并在索引列上做任何操作(计算、函数、自动or手动类型转换),这些会导致索引失效而转向全表扫描

4、存储引擎不能使用索引中范围条件右边的列,范围之后的索引全失效

5、尽量使用覆盖索引(之访问索引的查询(索引列和查询的列一致)),减少select *

6、mysql在使用不等于(!=、>、<)的时候无法使用索引会导致全表扫描。

7、is null、is not null也无法使用索引。

8、like以通配符开头("%abc.."),mysql索引失效也会变成全表扫描的操作。

9、字符串不加单引号也会引起索引失效

10、少用or,用它来连接时会索引失效。

1、对于单值索引,尽量选择针对当前query过滤性更好的索引

2、在选择组合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,位置越靠前越好

3、在选择组合索引的时候,尽量选择尽可能包含当前query中的where字句中更多字段的索引

4、尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。

全值匹配我最爱,最左前缀要遵守

带头大哥不能死,中间兄弟不能断

索引列上少计算,范围之后全失效

like百分写最右,覆盖索引不写里

不等空值还有or,索引失效要少用

var引号不可丢,sql高级也不难

㈡ 如何优化SQL语句

一、问题的提出
在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性。
在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出高性能的SQL语句。
二、SQL语句编写注意问题
下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。
1.
IS
NULL

IS
NOT
NULL
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。
任何在where子句中使用is
null或is
not
null的语句优化器是不允许使用索引的。
2.
联接列
对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的。我们一起来看一个例子,假定有一个职工表(employee),对于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),现在要查询一个叫比尔.克林顿(Bill
Cliton)的职工。
下面是一个采用联接查询的SQL语句,
select
*
from
employss
where
first_name||''||last_name
='Beill
Cliton';
上面这条语句完全可以查询出是否有Bill
Cliton这个员工,但是这里需要注意,系统优化器对基于last_name创建的索引没有使用。
当采用下面这种SQL语句的编写,Oracle系统就可以采用基于last_name创建的索引。
***
where
first_name
='Beill'
and
last_name
='Cliton';
.
带通配符(%)的like语句
同样以上面的例子来看这种情况。目前的需求是这样的,要求在职工表中查询名字中包含cliton的人。可以采用如下的查询SQL语句:
select
*
from
employee
where
last_name
like
'%cliton%';
这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。然而当通配符出现在字符串其他位置时,优化器就能利用索引。在下面的查询中索引得到了使用:
select
*
from
employee
where
last_name
like
'c%';
4.
Order
by语句
ORDER
BY语句决定了Oracle如何将返回的查询结果排序。Order
by语句对要排序的列没有什么特别的限制,也可以将函数加入列中(象联接或者附加等)。任何在Order
by语句的非索引项或者有计算表达式都将降低查询速度。
仔细检查order
by语句以找出非索引项或者表达式,它们会降低性能。解决这个问题的办法就是重写order
by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order
by子句中使用表达式。
5.
NOT
我们在查询时经常在where子句使用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以使用and(与)、or(或)以及not(非)。NOT可用来对任何逻辑运算符号取反。下面是一个NOT子句的例子:
...
where
not
(status
='VALID')
如果要使用NOT,则应在取反的短语前面加上括号,并在短语前面加上NOT运算符。NOT运算符包含在另外一个逻辑运算符中,这就是不等于(<>)运算符。换句话说,即使不在查询where子句中显式地加入NOT词,NOT仍在运算符中,见下例:
...
where
status
<>'INVALID';
对这个查询,可以改写为不使用NOT:
select
*
from
employee
where
salary<3000
or
salary>3000;
虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。
虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。

㈢ 如何进行SQL优化请写出三种以上的方法,并分别做出解释说明

摘要 1:mysql所在服务器内核 优化;此优化可由系统运维人员完成

㈣ SQL语句优化问题

先用一个子查询判断+统计结果 然后外面套一个查询

select from orders o, (select max(id) mid,sum(qty) from orders group by shipp_house ) A
where o.id=a.mid
只是提供一个思路

㈤ SQL优化问题(求大神)

selectDate,id,Namefrom(
SELECTDate,Avg(id)id,Name
,row_number()over()asseq
FROM#
GROUPBYNAME,Date
)Fwhereseq=1

这个语句只会进行一次表扫描(或索引扫描)。而你原来的语句,会进行两次表扫描(或索引扫描)和一次join。

㈥ SQL 语句优化问题

事实上,这样的担心是不必要的。SQL
SERVER中有一个“查询分析优化器”,它可以计算出WHERE子句中的搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。
虽然查询优化器可以根据WHERE子句自动的进行查询优化,但仍然有必要了解一下“查询优化器”的工作原理,如非这样,有时查询优化器就会不按照您的本意进行快速查询。
在查询分析阶段,查询优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用。如果一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的,并且可以利用索引快速获得所需数据。
SARG的定义:用于限制搜索的一个操作,因为它通常是指一个特定的匹配,一个值得范围内的匹配或者两个以上条件的AND连接。形式如下:
列名
操作符
<常数

变量>或<常数

变量>
操作符列名
列名可以出现在操作符的一边,而常数或变量出现在操作符的另一边。如:
Name=’张三’价格>5000
5000<价格
Name=’张三’
and
价格>5000
如果一个表达式不能满足SARG的形式,那它就无法限制搜索的范围了,也就是SQL
SERVER必须对每一行都判断它是否满足WHERE子句中的所有条件。所以一个索引对于不满足SARG形式的表达式来说是无用的。
常见的SARG判别经验:
Like语句是否属于SARG取决于所使用的通配符的类型
如:name
like
‘张%’,这就属于SARG
而:name
like
‘%张’,就不属于SARG。
原因是通配符%在字符串的开通使得索引无法使用。
or
会引起全表扫描。
Name
=
’张三’
AND
价格>5000,符合SARG,
Name
=
’张三’
OR
价格>5000,不符合SARG。
原因是使用or会引起全表扫描。
非操作符、函数引起的不满足SARG形式的语句。
不满足SARG形式的语句最典型的情况就是包括非操作符的语句,如:NOT、!=、<>、!<、!>、NOT
EXISTS、NOT
IN、NOT
LIKE等,另外还有函数。下面就是几个不满足SARG形式的例子:
ABS(价格)<5000
Name
like
‘%三’
有些表达式,如:WHERE
价格*2>5000
SQL
SERVER也会认为是SARG,SQL
SERVER会将此式转化为:价格>5000/2
但不推荐这样使用,因为有时SQL
SERVER不能保证这种转化与原始表达式是完全等价的。

㈦ sql优化的几种方法面试

1.你把学校里面学的东西都弄通,弄懂就可以了,基本的概念和原理都能说出来,如你说的sql优化就是:为数据库建立索引,如何提高检索速度之类的问题。教科书上都有说啊。
2.面试不是说一定要什么都懂才能去面的,你要找多一点面试经验,面试经常问什么问题,比如指针,链表等,有针对性地准备一下,不用全部一骨碌地看。
3.积累经验和编程作品,多做项目,自己多写些程序。面试就有了筹码。

㈧ sql期末考试试题及答案

查询题:1).select*fromEMPwhereDEPTNO='20';2).select*fromEMPwhereENAMElike'MA%';3).select*fromEMPorderbyJOB;4).selectb.DNAME,COUNT(a.*)asnumfromEMPaleftjoinDEPTbona.DEPTNO=b.DEPTNOgroupbyb.DNAME5).select*fromEMPwhereSAL>(selectmax(SAL)asSALfromEMPwhereDEPTNO='20');程序题:1).函数:CREATEFUNCTION[SumN](@nINT)RETURNSINTASBEGINdeclare@outINT,@iintset@out=0set@i=1while@i<=@nbeginset@out=@out+@iset@i=@i+1endreturn(@out)END2).存储过程:CREATEPROCEDURE[emp_info](@nDECIMAL(2))ASselect*fromEMPwhereDEPTNO=@n视图和索引1).CREATEVIEW[emp10_view]ASselect*fromEMPwhereDEPTNO='10'2).ALTERTABLE[EMP]ADDCONSTRAINT[IX_Empno]PRIMARYKEYCLUSTERED([empno]ASC)

㈨ 一些SQL的试题

1.应用程序
2.实体完整性
3.distince
4.
5.create Nonclustered index IDX_authors on authors(州名列,城市名列)
6.创建表
7.select 列名 from 表名
8.sum()
9.top
10.alter procere
11.ltrim()
12.declare @变量名 数据类型
13.where
14.from
15.order by
16.cast(表达式 as 数据类型)
17.count()
18.drop procere 存储过程名
19.创建数据库
20.价格大于15美元的所有数据
21.数据库
22.rollback
23.
24.服务管理器
25.
26.数据冗余(备份)
27.3
28.数据库
29.应用程序
30.drop table
33.操作系统
权限
1.
2.是并发控制的单位,是用户定义的一个操作序列,具有原子性,一致性,隔离性,持续性四个特性。
3.共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁.
获准共享锁的事务只能读数据,不能修改数据。
4.
5.
1.存储过程可以使得程序执行效率更高、安全性更好,因为过程建立之后 已经编译并且储存到数据库,直接写sql就需要先分析再执行因此过程效率更高,直接写sql语句会带来安全性问题,如:sql注入
2.建立过程不会很耗系统资源,因为过程只是在调用才执行。
6.聚簇索引是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。
7.
8.是并发控制的单位,是用户定义的一个操作序列,具有原子性,一致性,隔离性,持续性四个特性。
BEGIN TRAN [Tran_name]开始事务
COMMIT TRAN [Tran_name]事务完成提交事务
9.存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。
10.增量备份:是针对于上一次备份(无论是哪种备份):备份上一次备份后,所有发生变化的文件。
12.原子性,要么都做,要么不做。
13.排它锁若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。
它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。
14.分布式数据库系统通常使用较小的计算机系统,每台计算机可单独放在一个地方,每台计算机中都有DBMS的一份完整拷贝副本,并具有自己局部的数据库,位于不同地点的许多计算机通过网络互相连接,共同组成一个完整的、全局的大型数据库。
15.
17同2,18同8
19.DBMS数据库管理系统,DBA数据库管理员
20.1对1,一个学生对应一个学号
1对多 一个学生对应多门功课
多对多 商品与厂商
(备注:只能做这么多了,很长时间没看书了,有时间可以看看<数据库系统概论>萨师煊 王珊 高等教育出版社,很不错的一本书哦。上有你要的答案,特别是简答题。)
21.
22.数据库完整性,对数据库提出的某种约束条件或规则。
分三种:实体完整性,参照完整性,用户自定义完整性
23.
24.原则如下:
●在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。
●在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。
●在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。
●如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。

26。聚集索引确定表中数据的物理顺序。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引)
非聚集索引一种索引,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。一个表可以有多个聚集索引

㈩ SQL执行与优化

SQL优化

执行计划,表关联查询顺序,优化策略与思路

下面再向前走一些,容我根据自己的认识说一下查询执行的流程是怎样的:

1.连接

1.1客户端发起一条Query请求,监听客户端的‘连接管理模块’接收请求

1.2将请求转发到‘连接进/线程模块’

1.3调用‘用户模块’来进行授权检查

1.4通过检查后,‘连接进/线程模块’从‘线程连接池’中取出空闲的被缓存的连接线程和客户端请求对接,如果失败则创建一个新的连接请求

2.处理

2.1先查询缓存,检查Query语句是否完全匹配,接着再检查是否具有权限,都成功则直接取数据返回

2.2上一步有失败则转交给‘命令解析器’,经过词法分析,语法分析后生成解析树

2.3接下来是预处理阶段,处理解析器无法解决的语义,检查权限等,生成新的解析树

2.4再转交给对应的模块处理

2.5如果是SELECT查询还会经由‘查询优化器’做大量的优化,生成执行计划

2.6模块收到请求后,通过‘访问控制模块’检查所连接的用户是否有访问目标表和目标字段的权限

2.7有则调用‘表管理模块’,先是查看table cache中是否存在,有则直接对应的表和获取锁,否则重新打开表文件

2.8根据表的meta数据,获取表的存储引擎类型等信息,通过接口调用对应的存储引擎处理

2.9上述过程中产生数据变化的时候,若打开日志功能,则会记录到相应二进制日志文件中

3.结果

3.1Query请求完成后,将结果集返回给‘连接进/线程模块’

3.2返回的也可以是相应的状态标识,如成功或失败等

3.3‘连接进/线程模块’进行后续的清理工作,并继续等待请求或断开与客户端的连接

接下来再走一步,让我们看看一条SQL语句的前世今生。

首先看一下示例语句

示例语句

执行顺序

SQL解析

1. FROM

当涉及多个表的时候,左边表的输出会作为右边表的输入,之后会生成一个虚拟表VT1。

(1-J1)笛卡尔积

计算两个相关联表的笛卡尔积(CROSS JOIN) ,生成虚拟表VT1-J1。

两次全表扫描

哈希索引,查找复杂度都是 O(1)

2. WHERE

对VT1过程中生成的临时表进行过滤,满足WHERE子句的列被插入到VT2表中。

注意:

此时因为分组,不能使用聚合运算;也不能使用SELECT中创建的别名;

与ON的区别:

如果有外部列,ON针对过滤的是关联表,主表(保留表)会返回所有的列;

如果没有添加外部列,两者的效果是一样的;

应用:

对主表的过滤应该放在WHERE;

对于关联表,先条件查询后连接则用ON,先连接后条件查询则用WHERE;

hash join 哈希连接 驱动表和被驱动表都只会访问0次或1次

应用场景:一个大表一个小表/表上没有索引/返回结果集比较大

3. GROUP BY

这个子句会把VT2中生成的表按照GROUP BY中的列进行分组。生成VT3表。

注意:

其后处理过程的语句,如SELECT,HAVING,所用到的列必须包含在GROUP BY中,对于没有出现的,得用聚合函数;

原因:

GROUP BY改变了对表的引用,将其转换为新的引用方式,能够对其进行下一级逻辑操作的列会减少;

原作者的理解是:

根据分组字段,将具有相同分组字段的记录归并成一条记录,因为每一个分组只能返回一条记录,除非是被过滤掉了,而不在分组字段里面的字段可能会有多个值,多个值是无法放进一条记录的,所以必须通过聚合函数将这些具有多值的列转换成单值;

GROUP BY 重新聚合查询

4. HAVING

这个子句对VT3表中的不同的组进行过滤,只作用于分组后的数据,满足HAVING条件的子句被加入到VT4表中。

7.LIMIT

LIMIT子句从上一步得到的VT6虚拟表中选出从指定位置开始的指定行数据。

注意:

offset和rows的正负带来的影响;

当偏移量很大时效率是很低的,可以这么做:

采用子查询的方式优化,在子查询里先从索引获取到最大id,然后倒序排,再取N行结果集

采用INNER JOIN优化,JOIN子句里也优先从索引获取ID列表,然后直接关联查询获得最终结果

当前未用到索引,

三次full scan , table1 AS a / table2 AS b / GROUP BY

尽量少做重复的工作

控制同一语句的多次执/减少多次的数据转换/

杜绝不必要的子查询和连接表,子查询在执行计划一般解释成外连接,多余的连接表带来额外的开销

关于临时表和表变量的选择

临时表产生使用SELECT INTO和CREATE TABLE + INSERT INTO的选择,一般情况下,SELECT INTO会比CREATE TABLE + INSERT INTO的方法快很多,但是SELECT INTO会锁定TEMPDB的系统表SYSOBJECTS、SYSINDEXES、SYSCOLUMNS,在多用户并发环境下,容易阻塞其他进程,所以建议,在并发系统中,尽量使用CREATE TABLE + INSERT INTO,而大数据量的单个语句使用中,使用SELECT INTO。

子查询的用法

相关子查询可以用IN、NOT IN、EXISTS、NOT EXISTS引入

NOT IN、NOT EXISTS的相关子查询可以改用LEFT JOIN代替写法

如果保证子查询没有重复 ,IN、EXISTS的相关子查询可以用INNER JOIN 代替

IN``的相关子查询用EXISTS代替

不要用 COUNT (*)的子查询判断是否存在记录,最好用 LEFT` `JOIN 或者EXISTS,比如有人写这样的语句:

建立索引后,并不是每个查询都会使用索引,在使用索引的情况下,索引的使用效率也会有很大的差别。只要我们在查询语句中没有强制指定索引,

不要对索引字段进行运算,而要想办法做变换

不要对索引字段进行格式转换

不要对索引字段使用函数

不要对索引字段进行多字段连接

join关联查询的计算是很复杂的,特别是数据量比较大的情况下,实际情况还是拆解较快的

Join拆解的核心就是利用In关键字

要么用空间换时间,要么用时间换空间

多表连接的连接条件对索引的选择有着重要的意义,所以我们在写连接条件条件的时候需要特别注意。

A、多表连接的时候,连接条件必须写全,宁可重复,不要缺漏。

B、连接条件尽量使用聚集索引

C、注意ON、WHERE和HAVING部分条件的区别

ON是最先执行, WHERE次之,HAVING最后,因为ON是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,WHERE也应该比 HAVING快点的,因为它过滤数据后才进行SUM,在两个表联接时才用ON的,所以在一个表的时候,就剩下WHERE跟HAVING比较了

考虑联接优先顺序:

(1)INNER JOIN

(2)LEFT JOIN (注:RIGHT JOIN 用 LEFT JOIN 替代)

(3)CROSS JOIN

索引并不适用于所有情况:a.少量数据;b.频繁进行改动的字段,不适合做索引;c.很少使用的字段,不需要加索引

索引会提高数据查询效率,但是会降低“增、删、改”的效率。当不使用索引的时候,我们进行数据的增删改,只需要操作源表即可,但是当我们添加索引后,不仅需要修改源表,也需要再次修改索引,很麻烦。

先执行顺序, 是否走索引, 有无类型转换

18000 字的SQL优化大全

步步深入:MySQL架构总览->查询执行流程->SQL解析顺序

MySQL索引总结(4)——btree与hash区别