㈠ 如何优化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、尽可能建立索引,包括条件列,连接列,外键列等。
2、尽可能让where中的列顺序与复合索引的列顺序一致。
3、尽可能不要select *,而只列出自己需要的字段列表。
4、尽可能减少子查询的层数。
5、尽可能在子查询中进行数据筛选 。
㈢ 一条sql执行过长的时间,你如何优化,从哪些方面
1、查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)
2、涉及链表的查询,是否能进行分表查询,单表查询之后的结果进行字段整合
3、如果以上两种都不能操作,非要链表查询,那么考虑对相对应的查询条件做索引。加快查询速度
4、针对数量大的表进行历史表分离(如交易流水表)
5、数据库主从分离,读写分离,降低读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现 主从同步
6、explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等
7、查看mysql执行日志,看看是否有其他方面的问题
个人理解:从根本上来说,查询慢是占用mysql内存比较多,那么可以从这方面去酌手考虑
㈣ 如何进行SQL优化请写出三种以上的方法,并分别做出解释说明
摘要 1:mysql所在服务器内核 优化;此优化可由系统运维人员完成
㈤ SQL语句如何优化
你要找最大并发数,就是根据你原逻辑,就是Records表每次开始、结束时间段内存在多少单。这样数据库会针对Records表的100万条记录,将Records自己进行执行。但是并不是“最大并发”而是“每个电话通话时长内有多少个电话在打入或打出”本来逻辑都错了。
你要优化的话。自己写个循环遍历一次,记录到临时表中。
临时表把 select top 1 starttime from Records order by id 作为开始时间
把 select top 1 starttime from Records order by id desc 作为结束时间
如果考虑算法速度的话和排除最少通话时段的时间与判断每天同话数是否大于现当前算出的最大通话时间。能减少不必要的消耗。
㈥ 怎样进行sql数据库的优化
1、数据库空间是个概述,在sqlserver里,使用语句 exec sp_spaceused 'TableName' 这个语句来查。
㈦ 怎么优化这条sql
case when 的效率低于isnull(),这是第一个要改的
-----------------------------------------------------------
然后可以使用表表达式来优化查询语句本身,表表达式在查询中只执行一次,这就避免了一些重复的工作 。
started与endeds可以共用一个表表达式:
select storeUuid
,case when createOpeTime < #{starttime} then 0 else 1 end started
,max(createOpeTime) createOpeTime
from store_capital_virtual_account_detail
where createOpeTime >= #{endtime}
group by storeUuid
,case when createOpeTime < #{starttime} then 0 else 1 end
类似的,added与reced也可以共用一个表表达式:
select storeUuid
,inOrOut
,sum(operAmount) add_amount
from store_capital_virtual_account_detail
where (inOrOut=1 or (inOrOut=1 and businessType != 52))
and createOpeTime between #{starttime} and #{endtime}
group by storeUuid,inOrOut
------------------------------------------------------------
再然后如果还需要进一步优化,那么,就要考虑那些可选的条件了。例如,where 条件直接写成smi.storeName LIKE .... and smi.storeNo LIKE ...,对参数进行预处理,没有它们就处理为''
如果能够限定这两个参数至少有一个不为空,那么,可以预见smi集就会小很多,那么,可以进一步把smi相关的查询部分也做成cte,并且用它们对cte_1和cte_2进行过滤以减少cte_1和cte_2做group时前中间集的大小,就能进一步提高效率。
----------------------------------------------------------
如果还不能满足需要,那么,还可以对表结构进行优化。
很多使用java的程序员设计表时为了方便,将很多字段都设计为字符类型,这减少了java代码中对类型的转换处理,但是,查询过程中计算压力都转稼到了sql引擎。当数据量大的时候,对字符字段的搜索效率是远低于一个适当的字段类型的,因为在查询过程中动态索引时,字段宽度与索引时间是强相关的。
inOrOut可以定义为tinyint,这只需要一个字节,可以存放256个不同的值(0~255或-128~127),记录时间的字段首选timestamp,如果不能满足需要可用datetime,它们分别需要4字节与8字节存储空间。
㈧ 2020-10-11:一条sql语句执行时间过长,应该如何优化从哪些方面进行优化
改进数据库sql语句进行优化的理由 应用程序之优化通常可分为两个方面:源代码之优化和sql语句之优化。源代码之优化在时间成本和风险上代价很高;另一方面,源代码之优化对数据库系统性能之提升收效有限。 优化之理由 1)sql语句是对数据库(数据)进行操作之惟一途径; 2)sql语句消耗了70%~90%之数据库资源; 3)sql语句独立于程序设计逻辑,相对于对程序源代码之优化,对sql语句之优化在时间成本和风险上之代价都很低; 4)sql语句可以有不同之写法; 5)sql语句易学,难精通。 优化技术之发展 第一代之sql优化工具是执行计划分析工具。这类之工具对输入之sql语句从数据库提取执行计划,并解释执行计划中关键字之含义;第二代之sql优化工具只能提供增加索引之建议,它通过对输入之sql语句之执行计划之分析来产生是否要增加索引之建议。该类工具存在着致命之缺点——只分析了一条sql语句就得出增加某个索引之结论,根本不理会(实际上也无法评估到)增加之索引对整体数据库系统性能之影响。其破坏性在于: 1、不理会增加之索引对其他增、删、改sql语句之负面影响; 2、没有考虑增加之索引可能导致数据库判断失误; 3、对由于增加索引引起之数据库系统负担忽略不计。 同时,这些工具由于技术水平之限制存在着以下缺点: 1、无法保证建议或改写之正确性; 2、无法进行重写,仅仅提供了建议或有限程度之改写,重写工作还是需要人工完成,优化工作所需之时间和工作量同人工进行优化差不多; 3、改写之规则和hints有限,难以处理复杂之sql语句; 4、必须人手逐条进行测试。 这类工具曾经盛极一时,直到人工智能自动sql优化之出现。
㈨ 如何进行SQL性能优化
这里分享下mysql优化的几种方法。
1、首先在打开的软件中,需要分别为每一个表创建 InnoDB FILE的文件。
㈩ 开发中,SQL语句优化有哪些方法
看你数据库类型和框架是否支持。
一般开发中遇到慢SQL存在3个问题(索引健全的情况下)。
数据量多导致总行数慢,因为数据在不归档、迁移、转总账的情况下会不断积压。权限越高看见的数据量就越大,数据量越大总行数就越高。一般框架是以分页的SQL为基础计算总行数的。这样就会导致扫描行数高物理读高查询速度慢。优化方案就是总行数进行状态归档,以归档+实时的方式展现出来
连表超过多,部分数据表是单独的,但是不同部门的数据又有关联性,领导要看全生命周期或者流程数据的情况下必须多表相连。这样由于N个明细表导致笛卡儿积先不说,逻辑复杂连表多会消耗CPU,哪怕你查询能500毫秒内显示但是如果多人同时查就让CPU超100%甚至做成锁等待等堵塞。这个情况就是要用类似“云计算”的分布式计算。通过触发器、存储过程等规定时间内吧业务表数据计算好并写到展示表中,直接通过展示表进行关联,这样锁表也于业务表无关,关联表也能变少达到减少CPU消耗的目的。
iops与cpu占比高导致数据库瘫痪。第2点看出如果CPU高数据库全SQL都会慢,IOPS也一样。SQL慢会导致事务中的查询慢,解放事务变慢了其他查询就会锁等待状态变成堵塞。所以遇到大规模的查询是否先查主键然后通过游标一个一个计算再进临时表。这个是消耗时间和内存换CPU和IOPS的一个例子。反正服务器资源最高怎样开发应该是了解的,如何管制资源之间的平衡这个很重要。
举个例子,部分MYSQL框架喜欢一次性把数据库都导出来,然后减少子查询,这个算法针对有效的基础数据这样是可行的。针对业务数据应该没人会用,但是基础数据中也可能会存在海量的情况,比如坐标轨迹、省市区、电话号码归属等。如果无脑应用这个框架会导致查询起来很慢。