㈠ 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语句可以提高数据库的执行速度应该注意那些
这个范围太大了,一下子是很难说清楚的,如果用sql
server
的话,可以使用它自带的优化器来优化,然后看看它给你的建议去优化。要注意规范化编程。而且要抓住一个原则来写,就是进可能缩小查询出来的结果集,哪怕多次查询都没所谓,要一步一步把大数据量缩小。很多只是还是得在时间中优化。SET
STATISTICS
TIME
ON;SQL
语句SET
STATISTICS
TIME
OFF;这个是sqlserver
,可以测出执行时间。编写的时候要时刻想着:缩小结果集、减少连接次数和表数。大数据量不要用update,可以用临时表作为过度来实现update操作。
㈢ 如何做SqlServer 数据查询优化!
一、建立索引
二、建立存储过程
三、只查询您所需要的数据,不要把所有数据都查询出来,防止数据冗余。
四、对于大量及海量数据一般还要建立分区
㈣ 如何解决SQL查询速度太慢
1. 执行计划中明明有使用到索引,为什么执行还是这么慢?
2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100 多万行?
a. 我们先看执行计划,选择的索引 “INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。
那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段区分度太低了,走这个索引需要扫描的行数很大,而且还要进行额外的排序,优化器综合判断代价更大,所以就不选这个索引了。不过如果我们强制选择这个索引(用 force index 语法),会看到 SQL 执行速度更快少于 10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;
b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。
Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,得保证 type 至少达到 range 级别,最好能达到 ref。
在第 2 点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;
c. 关于执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。
4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
优化过程:
TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引后执行计划:
这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
执行时间从 10s+ 降到 毫秒级别:
1 row in set (0.00 sec)
结论
一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:执行计划使用索引并不意味着就能执行快。
㈤ SQL Server数据库的高性能优化经验总结
本文主要向大家介绍的是正确优化SQL
Server数据库的经验总结,其中包括在对其进行优化的实际操作中值得大家注意的地方描述,以及对SQL语句进行优化的最基本原则,以下就是文章的主要内容描述。
优化数据库的注意事项:
1、关键字段建立索引。
2、使用存储过程,它使SQL变得更加灵活和高效。
3、备份数据库和清除垃圾数据。
4、SQL语句语法的优化。(可以用Sybase的SQL
Expert,可惜我没找到unexpired的序列号)
5、清理删除日志。
SQL语句优化的基本原则:
1、使用索引来更快地遍历表。
缺省情况下建立的索引是非群集索引,但有时它并不是最佳的。在非群集索引下,数据在物理上随机存放在数据页上。合理的索引设计要建立在对各种查询的分析和预测上。
一般来说:
①.有大量重复值、且经常有范围查询(between,
>,<
,>=,<
=)和order
by、group
by发生的列,可考虑建立群集索引
②.经常同时存取多列,且每列都含有重复值可考虑建立组合索引;
③.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。
2、IS
NULL
与
IS
NOT
NULL
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。任何在where子句中使用is
null或is
not
null的语句优化器是不允许使用索引的。
3、IN和EXISTS
EXISTS要远比IN的效率高。里面关系到full
table
scan和range
scan。几乎将所有的IN操作符子查询改写为使用EXISTS的子查询。
4、在海量查询时尽量少用格式转换。
5、当在SQL
SERVER
2000中
如果存储过程只有一个参数,并且是OUTPUT类型的,必须在调用这个存储过程的时候给这个参数一个初始的值,否则会出现调用错误。
6、ORDER
BY和GROPU
BY
使用ORDER
BY和GROUP
BY短语,任何一种索引都有助于SELECT的性能提高。注意如果索引列里面有NULL值,Optimizer将无法优化。
7、任何对列的操作都将导致表扫描,它包括SQL
Server数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
8、IN、OR子句常会使用工作表,使索引失效。如果不产生大量重复值,可以考虑把子句拆开。拆开的子句中应该包含索引。
9、SET
SHOWPLAN_ALL>10、谨慎使用游标
在某些必须使用游标的场合,可考虑将符合条件的数据行转入临时表中,再对临时表定义游标进行操作,这样可使性能得到明显提高。
注释:所谓的优化就是WHERE子句利用了索引,不可优化即发生了表扫描或额外开销。经验显示,SQL
Server数据库性能的最大改进得益于逻辑的数据库设计、索引设计和查询设计方面。反过来说,最大的性能问题常常是由其中这些相同方面中的不足引起的。
其实SQL优化的实质就是在结果正确的前提下,用优化器可以识别的语句,充份利用索引,减少表扫描的I/O次数,尽量避免表搜索的发生。其实SQL的性能优化是一个复杂的过程,上述这些只是在应用层次的一种体现,深入研究还会涉及SQL
Server数据库层的资源配置、网络层的流量控制以及操作系统层的总体设计。
㈥ 求优化sqlserver语句,使它查询效率提高。(要求:分组查询每组最新的一条数据,数据量非常大,几十万)
关于题主的SQL语句提高效率的问题,请留意一下几点
1) 输出的字段列表里只有来自表“dbo.tunnel_online_monitoring ”里的字段信息,没有任何来字段取自表“dbo.Threshold_ElectronicPool”,而且语句也没为这两张表指定连接条件,因此将表“dbo.Threshold_ElectronicPool”引入语句中就没有任何必要,加入该表只会大大增加系统开销,而无得益,应予以剔除;
2)row_number()函数的系统开销是比较大的,能不用尽量别用它。
如果dbo.tunnel_online_monitoring.Id是唯一的,可以不使用row_number()函数,建议语句修改如下:
selectId,CreationDate,LastUpdate,tunnel_name,
SDMC,DT,DZSC1,DZSC2,DZSC3from
tunnel_online_monitoringwhereidin(
selectmax(a.id)fromdbo.tunnel_online_monitoringa,
(selecttunnel_name,max(CreationDate)asCreationDatefrom
dbo.tunnel_online_monitoringgroupbytunnel_name)b
wherea.tunnel_name=b.tunnel_nameanda.CreationDate
=b.CreationDategroupbyb.tunnel_name);
如果dbo.tunnel_online_monitoring.Id是自增ID,那么可以根据ID的大小来判定那条记录是最新的,这样就不需要比对时间字段的先后了,语句可简化如下:
selectId,CreationDate,LastUpdate,tunnel_name,
SDMC,DT,DZSC1,DZSC2,DZSC3from
tunnel_online_monitoringwhereidin(
selectmax(id)fromdbo.tunnel_online_monitoring
groupbytunnel_name);
如果dbo.tunnel_online_monitoring.Id不是唯一的,那就还是得利用回row_number()函数了。
㈦ SQL语句 优化问题,提高性能
唉。。。说的千奇百怪什么都有,真是。。。。
下面,说说我的看法:
首先,like '%asdasd%'会造成表扫描。
其次,like 'asdasd%'可能无法满足楼主的要求
再次,like 并不是只有查不到的时候才遍历全表,是每次都要遍历。
给楼主两个建议方案,第一就是给 关键字 字段建索引
例如 select * from table1 where id like '%qweqwe%'
此时如果id有索引,或者是主键,那么就应该不会构成表扫描。但是有时候也有例外,有时候一样的脚本,换换格式,效率也就不一样,相信是优化器的作用。
第二方案,查询没有数据的时候慢,那么楼主试试不要查出每条数据,用count(*)先查一下试试,如果结果为0,就不用查了。
不过不是很建议用第二方案,除非迫不得已。
还有,楼主可以用查询分析器分析一下脚本的效率,看看什么地方构成表扫描,改善一下即可
㈧ SQL优化问题
问题1,2,3,其实效率是一样高的,因为现在的sqlserver,oracle,都有sql语句优化分析器,语句不同的写法,到最后编译之后,其实是一样的。
4,如果对字段like,而且是%key%这样的方式,索引就不起作用了,所以加上索引也没用。
㈨ 怎样进行sql数据库的优化
1、数据库空间是个概述,在sqlserver里,使用语句 exec sp_spaceused 'TableName' 这个语句来查。
㈩ 怎么用SQL语句去优化数据库是SQLserver2005
通常情况下,即在数据库的数据量,服务器硬件都在承受范围内,进行的是:
1.语句调优,包括创建索引,优化语句的实现方式使执行计划更流畅
2.表结构变更,即在语句级别的调优没有办法满足性能要求的时候不得不采用的措施.包括表的拆分,横向拆分,纵向拆分等
还有其他的一些比较大的改动,包括服务器迁移,读写分离,分布式规划等等