select语句性能优化小结(精选5篇)

时间:2019-05-12 15:23:59下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《select语句性能优化小结》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《select语句性能优化小结》。

第一篇:select语句性能优化小结

对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num is null

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select id from t where num=0

3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num=10 or num=20 可以这样查询:

select id from t where num=10 union all

select id from t where num=20

5.in 和 not in 也要慎用,否则会导致全表扫描,如: select id from t where num in(1,2,3)

对于连续的数值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3

6.下面的查询也将导致全表扫描:

select id from t where name like '%abc%' 若要提高效率,可以考虑全文检索。

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

select id from t where num=@num 可以改为强制查询使用索引:

select id from t with(index(索引名))where num=@num

8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where num/2=100 应改为:

select id from t where num=100*2

9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where substring(name,1,3)='abc'--name以abc开头的id select id

from

t

where datediff(day,createdate,'2005-11-30')=0--„2005-11-30‟生成的id 应改为:

select id from t where name like 'abc%' select id from

t

where

createdate>='2005-11-30'

and createdate<'2005-12-1'

10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

12.不要写一些没有意义的查询,如需要生成一个空表结构:

select col1,col2 into #t from t where 1=0

这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样: create table #t(...)

13.很多时候用 exists 代替 in 是一个好的选择:

select num from a where num in(select num from b)用下面的语句替换:

select num from a where exists(select 1 from b where num=a.num)

14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。详细讲解提高数据库查询效率的实用方法

16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

18.尽可能的使用 varchar/nvarchar 代替 char/nchar,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

19.任何地方都不要使用 select * from t,用具体的字段列表代替“*”,不要返回用不到的任何字段。

20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table,然后 drop table,这样可以避免系统表的较长时间锁定。

25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON,在结束时设置 SET NOCOUNT OFF。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

29.尽量避免大事务操作,提高系统并发能力。

30.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.应尽量避免使用 left join 和 null 值判断。left join 比 inner join 消耗更多的资源,因为它们包含与 null(不存在)数据匹配的数据,所以如果可以重新编写查询以使得该查询不使用任何 inner join,则会得到相应的回报。

例如有两表: product(product_id int not null,product_type_id int null,...),产品表,product_id 为大于0的整数,product_type_id 与表 product_type 关联,但可为空,因为有的产品没有类别

product_type(product_type_id not null,product_type_name null,...),产品类别表

此时要关联两表后查询 product 的内容,马上会想到使用 inner join,但下面有一种方法可避免使用 inner join :

在 product_type 中增加一条记录:0,'',...,并将 product 的 product_type_id 设置为 not null,当产品没有类别时将其 product_type_id 设为0,这样查询就可以使用 inner join 了。

3.应尽量避免在 where 子句中使用!=或<>操作符,否则引擎可能放弃使用索引而进行全表扫描。

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将可能导致引擎放弃使用索引而进行全表扫描,如有表 t,key1、key2 上建有索引,需要下面的存储过程:

create procedure select_proc1 @key1 int=0,@key2 int=0 as begin

select key3 from t

where(@key1=0 or key1=@key1)and(@key2=0 or key2=@key2)end go

这个存储过程会导致全表扫描,可作如下修改:

create procedure select_proc2 @key1 int=0,@key2 int=0 as begin

if @key1 <>0 and @key2<>0 select key3 from t

where key1=@key1 and key2=@key2 else

if @key1<>0

select key3 from t where key1=@key1 else

select key3 from t where key2=@key2 end go

更改后虽然代码增加了,但效率提高了。

5.in 和 not in 也要慎用,如:

select id from t where num in(1,2,3)

对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3

6.下面的查询也将导致全表扫描:

select id from t where name like '%abc%' 若要提高效率,可以考虑全文检索。

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

select id from t where num=@num 可以改为强制查询使用索引:

select id from t with(index(索引名))where num=@num

8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where num/2=100 应改为:

select id from t where num=100*2

9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where substring(name,1,3)='abc'--name以abc开头的id select id from t where datediff(day,createdate,'2005-11-30')=0--„2005-11-30‟生成的id 应改为:

select id from t where name like 'abc%'

select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

12.不要写一些没有意义的查询,如需要生成一个空表结构:

select col1,col2 into #t from t where 1=0

这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:

create table #t(...)13.很多时候用 exists 代替 in 是一个好的选择:

select num from a where num in(select num from b)用下面的语句替换:

select num from a where exists(select 1 from b where num=a.num)

14.并不是所有索引对查询都有效,SQL 是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female 几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert、update 及 delete 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

18.尽可能的使用 varchar/nvarchar 代替 char/nchar,因为首先变长字段存储空间小,可以节省存储空间(定长字段即使在数据为null时也需要定长的存储空间(7.0及更高版本)),其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些,而且每页(8KB)可能存储更多的记录数,这样也可以减少I/O的消耗而提高性能。

19.任何地方都不要使用 select * from t,用具体的字段列表代替“*”,不要返回用不到的任何字段。

20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;如果数据量不大,为了缓和系统表的资源,应先 create table,然后 insert。

24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table,然后 drop table,这样可以避免系统表的较长时间锁定。

25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select id from t where num=0 2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。

3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num=10 or num=20 可以这样查询:

select id from t where num=10 union all select id from t where num=20 4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。如:

select id from t where num in(1,2,3)对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3 5.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。见如下例子:

SELECT * FROM T1 WHERE NAME LIKE ‗%L%‘ SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=‘L‘ SELECT * FROM T1 WHERE NAME LIKE ‗L%‘

即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。

6.必要时强制查询优化器使用某个索引,如在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描: select id from t where num=@num 可以改为强制查询使用索引:

select id from t with(index(索引名))where num=@num 7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: SELECT * FROM T1 WHERE F1/2=100 应改为: SELECT * FROM T1 WHERE F1=100*2 SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=‘5378‘ 应改为: SELECT * FROM RECORD WHERE CARD_NO LIKE ‗5378%‘ SELECT member_number, first_name, last_name FROM members WHERE DATEDIFF(yy,datofbirth,GETDATE())> 21 应改为: SELECT member_number, first_name, last_name FROM members WHERE dateofbirth < DATEADD(yy,-21,GETDATE())即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。

8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如: select id from t where substring(name,1,3)=‘abc‘–name以abc开头的id select id from t where datediff(day,createdate,‘2005-11-30′)=0–‗2005-11-30‘生成的id 应改为: select id from t where name like ‗abc%‘ select id from t where createdate>=‘2005-11-30′ and createdate<‘2005-12-1′

9.不要在 where 子句中的―=‖左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

10.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

11.很多时候用 exists是一个好的选择: select num from a where num in(select num from b)用下面的语句替换: select num from a where exists(select 1 from b where num=a.num)SELECT SUM(T1.C1)FROM T1 WHERE((SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)SELECT SUM(T1.C1)FROM T1WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。

如果你想校验表里是否存在某条纪录,不要用count(*)那样效率很低,而且浪费服务器资源。可以用EXISTS代替。如: IF(SELECT COUNT(*)FROM table_name WHERE column_name = ‗xxx‘)可以写成:

IF EXISTS(SELECT * FROM table_name WHERE column_name = ‗xxx‘)

经常需要写一个T_SQL语句比较一个父结果集和子结果集,从而找到是否存在在父结果集中有而在子结果集中没有的记录,如: SELECT a.hdr_key FROM hdr_tbl a—-tbl a 表示tbl用别名a代替

WHERE NOT EXISTS(SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)SELECT a.hdr_key FROM hdr_tbl a LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL SELECT hdr_key FROM hdr_tbl WHERE hdr_key NOT IN(SELECT hdr_key FROM dtl_tbl)三种写法都可以得到同样正确的结果,但是效率依次降低。12.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

13.避免频繁创建和删除临时表,以减少系统表资源的消耗。14.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

15.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

16.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table,然后 drop table,这样可以避免系统表的较长时间锁定。

17.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON,在结束时设置 SET NOCOUNT OFF。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。18.尽量避免大事务操作,提高系统并发能力。19.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

20.避免使用不兼容的数据类型。例如float和int、char和varchar、binary和varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如: SELECT name FROM employee WHERE salary > 60000 在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。

21.充分利用连接条件,在某种情况下,两个表之间可能不只一个的连接条件,这时在 WHERE 子句中将连接条件完整的写上,有可能大大提高查询速度。例:

SELECT SUM(A.AMOUNT)FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO SELECT SUM(A.AMOUNT)FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO AND A.ACCOUNT_NO=B.ACCOUNT_NO 第二句将比第一句执行快得多。

22、使用视图加速查询

把表的一个子集进行排序并创建视图,有时能加速查询。它有助于避免多重排序 操作,而且在其他方面还能简化优化器的工作。例如: SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 AND cust.postcode>―98000‖ ORDER BY cust.name 如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个视图中,并按客户的名字进行排序: CREATE VIEW DBO.V_CUST_RCVLBES AS SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 ORDER BY cust.name 然后以下面的方式在视图中查询: SELECT * FROM V_CUST_RCVLBES WHERE postcode>―98000‖

视图中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。

23、能用DISTINCT的就不用GROUP BY SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID 可改为:

SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10 24.能用UNION ALL就不要用UNION UNION ALL不执行SELECT DISTINCT函数,这样就会减少很多不必要的资源

35.尽量不要用SELECT INTO语句。

SELECT INOT 语句会导致表锁定,阻止其他用户访问该表。上面我们提到的是一些基本的提高查询速度的注意事项,但是在更多的情况下,往往需要反复试验比较不同的语句以得到最佳方案。最好的方法当然是测试,看实现相同功能的SQL语句哪个执行时间最少,但是数据库中如果数据量很少,是比较不出来的,这时可以用查看执行计划,即:把实现相同功能的多条SQL语句考到查询分析器,按CTRL+L看查所利用的索引,表扫描次数(这两个对性能影响最大),总体上看询成本百分比即可。

第二篇:SQL语句性能优化

我也做了很长时间医疗软件,也写过不少sql优化,没有详细记录下来,个人感觉下面转载的更符合医院医疗软件实际业务,很认可大部分所写的原则,固转载过来,以作借鉴。软件的根本还是在于更细更精,在于从客户的实际使用考虑问题。

性能优化原则1:永远避免困境

利用缓存把字典数据取到中间服务器或是客户端替代直接sql查询,如,门诊医生站把字典下载到客户端,减少执行次数。

一次性取数据到客户端,然后再逐条处理,而不是分次取数据,处理好一条数据再取下一条再处理。例:门诊收费取hjcfmxk例子,原来是一张处方条明细都查询一次,查询后再处理,现改为一次把所有明细都取过来,然后一条条处理

尽量减少光标,看能不能用临时表

性能优化原则2:kiss原则

对于where 条件中的左边可以利用索引的字段Keep it simple stupid,左边尽量避免用函数(substring,isnull,upper,lower),参加计算+,-*/

例子1:select * from ZY_BRFYMXK where substring(zxrq,1,8)='20081212‘

select * from ZY_BRFYMXK where zxrq between '2008121200' and '2008121224' 例子2:

select * from zy_detail_charge where SUBSTRING(patient_id,1,10)=

substring('000005090600',1,10)这句耗时30秒以上

select * from zy_detail_charge where patient_id like substring('000005090600',1,10)+'%' 这句耗时2秒以内

性能优化原则3:尽可能利用到索引

例:select * from ZY_BRFYMXK a(nolock),VW_LSYZK b(nolock)where a.syxh=3 and a.yzxh=b.xh and a.fylb=0

select * from ZY_BRFYMXK a(nolock),VW_LSYZK b(nolock)where a.syxh=3 and a.yzxh=b.xh and a.fylb=0 and b.syxh=3

性能优化原则4:or,避而远之

对于索引字段尽力避免用or,普通字段可以用or,解决要么分解成多个sql,要么用业务规则避免,例:declare @rq1 ut_rq16,@syxh ut_syxh

select @rq1='20081201'

select @syxh=157

性能优化原则5:避免大批量数据取到前台

例: select * from ZY_BRSYK cyrq between ‘20080901’ and ‘20081201‘,对于大医院每天100多人,90天是9000条数据

性能优化原则6:事务,尽可能的短吧

所有计算、对临时表的更新都应但放在事务外,事务中最好只有更新和插入正式表操作.因为事务中产生的锁只有在commit tran是才会释放。

性能优化原则7:热表,留在最后吧

热表是频繁调用的表。如:sf_mzcfk,zy_brfymxk,bq_fyqqk.对于热表尽量放在事务最后:这样锁的时间短。大家都坚持这样,死锁的可能性就小。如果都是热表各个存储过程更新表的顺序应当一样这样可以避免死锁

性能优化原则8:创建临时表一定要避免在事务中作

如create #tempXX(…)

Select * into #tempXX from …

因为创建临时表会锁tempdb的系统表

例:生成#temp1放在事务内外,用sp_lock2 ‘’观察结果

if object_id('tempdb..#temp1','U')is not null

drop table #temp1

begin tran

select * into #temp1 from ZY_BRSYK where ryrq>'20080901‘

select * from #temp1

waitfor delay '00:00:10'

commit

性能优化原则9:大的报表查询避免与正常业务碰撞

如果没有查询服务器,那要在存储过程中限制不能操作加上如:

declare @rq1 ut_rq16,@rq2 ut_rq16,@now ut_rq16

select @rq1=convert(varchar(8),getdate(),112)+'08:00:00'

select @rq1=convert(varchar(8),getdate(),112)+'11:30:00'

select @now=convert(char(8),getdate(),112)+convert(char(8),getdate(),8)

if @now>@rq1 and @now<@rq2

begin

select '上午繁忙时间段不能作此查询'

return

end

性能优化原则10:存储过程避免大的if…else…

这个常出项在业务相同表不同的存储过程中,因为这样常到if …else …原来医技接口中很多这种存储过程,当时把门诊住院业务放在一个存储过程中。这样最大的问题是sql server会根据sql语句来compile存储,这个过程会生成优化计划,决定用那个索引。如果存储过程用到门诊表compile一下,到用到住院表是发现不对,又会compile一下,这样不停compile.compile很号时间要1-2秒,而且一个存储过成在compile是,所有调用这个存储过程的进程都要在排队等候,因为他会独占锁这个存储过程

例:usp_yjjk_getwzxxm_old.sql,后改为:

usp_yjjk_getwzxxm.sql, usp_yjjk_getwzxxm_mz.sql,usp_yjjk_getwzxxm_zy.sql

性能优化原则11:进攻是最好的防守

在普通编程语句对于数据校验总是用防守办法先判断,后再作相应处理。而在sql中先处理再判断性能会好很多。

--更新药品库存。

If exists(select 1 from YK_YKZKC WHERE idm=100 and kcsl>50)

begin

update YK_YKZKC set kcsl=kcsl-50 where idm=100

End

Else begin

rollback tran

Select ‘F库存不够’

return

end

--改为

update YK_YKZKC set kcsl=kcsl-50 where idm=100 and kcsl>50

If @@rowcount<=0

Begin

Rollbakc tran

Select ‘F库存不够’

end

--取未执行的医技项目,日表没有数据就到年表中查找

if exists(select a.* from SF_MZCFK a(nolock),SF_CFMXK b(nolock)

begin

select a.* into #temp1 from SF_MZCFK a(nolock),SF_CFMXK b(nolock)

end

else begin

select a.* into #temp1 from SF_NMZCFK a(nolock),SF_NCFMXK b(nolock)

end

--改为

Insert into #temp1 select a.*

from SF_MZCFK a(nolock),SF_CFMXK b(nolock)

If @@rowcount=0

Begin

Insert into #temp1 select a.*

from SF_NMZCFK a(nolock),SF_NCFMXK b(nolock)

end

性能优化原则12:trig最后的手段

Trig(触发器)的处理的处理机制是满足条件时就会在源语句后面加上trig中的代码进行执行。

它有两个致命的弊端:(1)不清楚有trig的人会对于执行结果感到迷惑。如常有在插入一张表如果主键是indentity的值常取用select @@identity。但如是有trig,tring中有表插入操作,这时的@@identity可能就不是想要的值。(2)trig会束缚选择。如:有一套单据主表和明细表,当明细表的金额更新时,要同步主表的金额,当程序是一条条更新明细时用trig的作法是每当更新一条明细记录时都算一处所有明细表的总金额,再去更新主表的金额。这样有多少条明细就要算多少次,好的作法是不要trig,直接在sql语句中明细更新完明后,一次性算出总金额每条单据的总金额,再更新主表的金额。

对于trig如果有其他手段就一定要避免用trig.性能优化原则13:用户说好才是真的好

1)有时sql语句性能难以优化,但用户对于系统响应速度还是不满意。这时可以从业务分析处理。

如:我们退费模块录入发票号原来是用fph like ‘XXX%’。用户报怨慢,后来改为先用fph=‘XXX’来查,如查不到再fph like ‘XXX%’。这样在绝大部情况下速度都非常快,同时也满足小部分情况下模糊查询的需求。

如:我们的程序要查日表和年表。如果通过日表union表视图去查会非常慢,性能也难以优化。程序改为普通情况下不查年表,用户勾上年表标志时才查年表。

(2)查询统计很多数据时间比较长,就以查询完一部分数据后可以显示这部分数据或是用提示,这样用户清楚系统在作事情也知道大概进度。这样情绪上会好很多。

(3)查询模块常有一进入时也默认一个查询,如果性能好,查询又合用户心意,这种设计非常好,如果性能不好,那就不是好的设计。用户对于进入都困难的模块是没有好感的。

(4)有户的耐心与查询出的记录成正比。用户痛恨等待很久却没有查询出记录。

对于非常慢的查询,如果有些子查询非常快可以先作这样查询以避免查询很久却没有数据出来的情况。如:按病历号查在院病人所有费有明细,可以先查一下这个病历是不是有对应病人。

实战技巧1:用exists、in代替distinct

Distinct实际上是先收集再删除这样两步都耗资源。

Exists,in会隐式过滤掉重复的记录

例查自2009年以来有金额大于100的药品的病人

select distinct a.blh,a.hzxm from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock)where a.patid=b.patid and b.syxh=c.syxh and c.zxrq>'2009' and c.zje>100--改为

select a.blh,a.hzxm from ZY_BRXXK a where exists(select 1 from ZY_BRSYK

b(nolock),ZY_BRFYMXK c(nolock)where a.patid=b.patid and b.syxh=c.syxh and

c.zxrq>'2009'and c.zje>100)

实战技巧2:缩短union

select …from A,B,C,D,E1

where(E1的条件)

and(其他表联接条件)

union

select …from A,B,C,D,E2

where(E2的条件)

and(其他表接接条件)

改为

select …from A,B,C,D,(select...from E1where(E1条件)

union

select …from E2where(E2条件))E where(其他条件)

当涉及ABCD表部分耗资源而E1,E2不耗资源时是这样,如果反过来则改后的性能不一定好。查2009年4月后入院的在院病人在2905病区发生的所有费用明细

select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw

select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw

from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),YK_YPCDMLK d where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.idm=d.idm

union all

select a.hzxm,b.cyrq,d.name,d.xmgg,c.ypsl/c.dwxs ypsl, c.ypdw

from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),YY_SFXXMK d where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.ypdm=d.id and c.idm=0

--改为

select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw

from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),(select ypmc,ypgg,ypdm,idm idm from YK_YPCDMLK union select name,xmgg,id,0 from YY_SFXXMK)d

where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.idm=d.idm and c.ypdm=d.ypdm

实战技巧3:合并sql

把表和where条件类似的两个或是多个sql合并为一个sql.--查2009年以后的普通、急诊、专家挂号人数

declare @ptghs int,@jzghs int,@zjghs int

select @ptghs=0,@jzghs=0,@zjghs=0

select @ptghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=0

select @jzghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=1

select @zjghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=2

select @ptghs,@jzghs,@zjghs

--改为

select @ptghs=0,@jzghs=0,@zjghs=0

select @ptghs=sum(case when ghlb=0 then 1 else 0 end),@jzghs=sum(case when ghlb=1 then 1 else 0 end), @zjghs=sum(case when ghlb=2 then 1 else 0 end)

from GH_GHZDK where ghrq>'2009'

select @ptghs,@jzghs,@zjghs

实战技巧4:去掉游标

把游标当作编程语言的for,do---while的方式,很多情况下都可以去掉,如果光标中间sql语句只有一条一般都是可以去掉光标改为一句sql。

--查当天出院出院日期在2009年4月1到9日间病人的zfdj,zfje置为0

declare @syxh ut_syxh

declare cur1 cursor for select syxh from ZY_BRSYK where cyrq>='20090401' and cyrq<'20090410'

open cur1

fetch cur1 into @syxh

while @@fetch_status=0

begin

fetch cur1 into @syxh

end

close cur1

deallocate cur1

--改为

update ZY_BRFYMXK set zfdj=0,zfje=0

from ZY_BRFYMXK a,ZY_BRSYK b

where a.syxh=b.syxh and b.cyrq>='20090401' and b.cyrq<'20090410'

实战技巧5:取代count

利用内部函数代替

declare @count int

select * into #tmep1 from ZY_BRFYMXK WHERE zxrq>'200901'

select @count=@@rowcount—可以得到count值

select @count

select @count=count(*)from #tmep1—可以被取代

select @count

利用exists而不count判断有没有记录

declare @count int

Select @count=count(1)from ZY_BRFYMXK WHERE zxrq>'2009‘

If @count>0 … else ….--改为

If exists(Select 1 from ZY_BRFYMXK WHERE zxrq>'2009’)… else ….

第三篇:Web前端页面性能优化小结

Web前端页面性能优化小结

Web前端页面性能优化小结

影响用户访问的最大部分是前端的页面。网站的划分一般为二:前端和后台。我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等。而前端呢?其实应该是属于功能的表现。

而我们建设网站的目的是什么呢?不就是为了让目标人群来访问吗?所以我们可以理解成前端才是真正和用户接触的。

除了后台需要在性能上做优化外,其实前端的页面更需要在性能优化上下功夫,只有这样才能给我们的用户带来更好的用户体验。不仅仅如此,如果前端优化得好,他不仅可以为企业节约成本,他还能给用户带来更多的用户,因为增强的用户体验。说了这么多,那么我们应该如何对我们前端的页面进行性能优化呢?

前端的页面主要包括xhtml,css,js。其实xhtml就是现实中所谈到的内容,页面的内容:文字,图片,flash,视频等。

而前端开发工作者可以控制的是什么呢?那就是xhtml,css,js的代码及相应的修饰(背景)图片。下面我就根据我自己的经验来说说:

一、提倡前端开发工程师在书写xhtml的时候做到结构语义化。结构中主要包括了head和body两个部分,但是我们经常说的是结构语义化主要是body中的标签,但是我在这里还是简单的说一下 head,head中其实包括了一些对于我们seo很有用的一些东西,比如

title,description,keywords,这些东西在蜘蛛抓取的时候都是有帮助的,当然,还有其他的一些,我在此就不一一说明了,比如设置缓存等一些其他的信息。那么body中的话,包括的标签就很多了,我觉得作为一个合格的前端开发人员你应该去熟悉他们,比如div,span,h,ul,ol,dl,p等等这类的标签的使用。应该非常合理,还有就是注意h标签的断层,及h1标签的使用,这些都是非常重要的。同时在我们的结构中不要出现style和onclick这样的内联的样式和事件.。希望大家能够注意结构与表现、行为的分离。(ps:标签语义化的好处:1.有利于搜索引擎;2.结构清晰的html在团队合作中的作用,就不必说了吧;3.有利于盲人屏幕阅读器。至于如何做到标签语义化,就看个人的理解了,这方面我也觉得模糊,跟个人的习惯估计也有一定的关系,总之邹惠斌老师是认为我的标签不语义的。)

二、css(http://zhi.ujiuye.com/web/css/),js文件数量及大小的优化 那么关于css、js的优化的话,一般情况下建议css和js采用外联式。但是如果你的页面内容比较多,设计师把整个效果做得比较花的话,恐怕 css就非常多了,那么这种情况下,你一定要把你的css规划好,尽量的采用缩写,这样可以减少css文件的大小,那么对css做相应的规划也可以减少 css的个数,减少http请求数,js同理。(ps:减少重复性代码,代码重复利用,在这里显得特别重要)

三、背景图片数量及大小的优化

当我们将设计师的设计稿还原成静态页面后,除非页面所有的修饰全是色块,内容全是文字,没有图片,如果不是这样的话,那么我们需要对图片做优化处理。当然内容图片我们是没有办法了,因为他是属于内容部分的,一般情况是由于编辑处理,当然,我在还是有一个小小的建议,如果我们的网站中需要有内容图片,希望编辑能够将他们最优化以后,在进行上传,一会儿告诉我的方法,下面我在说说,作为前端开发应该如何处理我们的修饰(背景)图片。由于我们的背景图片数量比较多,这样的话,会给服务器带来影响,增加了http请求数,我们是否有一种好的解决办法呢?这个答案是肯定的,如果你是一个合格的前端开发,你应该清楚,在我们的css定义背景的时候,可以通过坐标来实现对背景进行定位的,既然如此,那么我们可以将这些背景合并起来,这样即可减少http请求数,同时,我们在背景整合的时候,也需要考虑图片质量,同时也需要考虑图片的大小(ps:这里建议使用png8格式的图片结合css sprite,同样的图片,png8格式会相对来比gif小)

四、内容图片的大小的优化

其实刚才已经说了内容图片的问题,那么我在这里呢,告诉大家一个比较简单的方法,就是使用雅虎提供的一个工具。他就是smushit:http:// 规范在文档 内加载你的样式表。

对于拥有较大浏览量的首页来说,有一种技术可以平衡内置代码带来的 http 请求减少与通过使用外部文件进行缓存带来的好处。其中一个就是在首页中内置 javascript 和 css,但是在页面下载完成后动态下载外部文件,在子页面中使用到这些文件时,它们已经缓存到浏览器了。

更多知识干货分享,尽在中公优就业,>>>点击进入。

点击查看>>>中公IT优就业封闭式培训,包食宿,学费贷款,交通补贴,推荐就业

第四篇:6多分支结构——select语句

第三节多分支结构——select语句教学设计

一、教学目标

1、知识与技能:

(1)充分理解多分支结构的流程。

(2)能够利用多分支结构的思想解决实际问题。

2、过程与方法: 培养学生独立思考的能力、灵活运用所学知识解决问题的能力。

3、情感态度与价值观:(1)增强学生思维的严密性。

(2)善于发现问题,敢于提出疑问并能够针对疑问积极主动的思考解决。

二、教学重难点

1、重点:理解多分支结构的流程。

2、难点:理解程序中流程的代码描述。

三、教学过程

1、游戏引入

通过学生喜欢的心理测试的小游戏再将学生的注意力吸引到本课中来的同时,让学生初步体会,选择不同的面包能够得到不同的测试结果。

(设计意图:从游戏入手,满足了学生爱玩的童心的同时,集中了学生的注意了,拉近了师生之间的距离,也为后面的问题做好铺垫。)

2、初步理解

教师通过解密心理测试的秘密引出游戏的背后的支持者:程序代码,带领学生边玩游戏边看代码,从中发现规律。同时提出问题:玩游戏的过程当中如果在文本框中输入3,测试结果变成“你是灰太狼”,要达到这个要求需要对游戏代码做怎样的修改?并说明原因

(代码是比较抽象的概念,很难通过定义理解它,通过修改代码从形式上让代码成为学生自己的东西,接触学生看到代码的陌生心理,同时让学生初步体会不同的选择对应不同的结果。)

3、深入剖析

通过理解星猫心理测试的过程,将不同的面包对应不同的测试结果转化为流程图中不同的条件对应不同的语句组,通过心理测试的代码导出程序基本格式。

(设计意图:图形是比较直观好理解的表现形式,通过图形引出结构的流程图,结合流程图分析该图是如何应用程序语句描述的,以具体的程序语句对照理解语句格式的基本结构也就不难了。)

4、模拟练习

以程序填空的形式完成分蛋游戏,进一步体会不同的年龄段对应不同的礼物,体验调试程序带来的快乐和成就感,在这一过程中要演示学生的成果,适时给出表扬。

(设计意图:对于初中学生来说,本节课只需要理解多分支结构的执行过程,理解不同的条件对应执行不同的语句组,代码只需要简单了解。通过流程图理解游戏在程序中的执行过程,在通过代码填空,加强对结构的理解。)

5、深入提高

通过思考心理测试当中没有想选择的面包的特殊情况的处理方法,引出当表达式对于条件1到条件N都不符合时的处理办法case else 语句组N+1.培养学生思考问题的严密性。

(设计意图:程序设计要求思维严密,考虑到所有可能出现的情况,通过具体的实例引领学生思考特殊情况并思考特殊情况的处理办法,这样就把抽象的问题具体化,能够帮助学生理解,并应用到解决问题的过程当中去。)

6、小结

通过两个游戏的流程图以及统一的流程图,进而引出专业术语多分支结构——select语句。

通过小结,把课堂教学传授的知识尽快化为学生的素质;使学生更深刻地理解两个游戏的执行流程的同时引出本课的课题,这种结构就是VB中的多分支结构,起到画龙点睛的作用。

7、知识深化

课后思考题:完成成绩评价系统,思考两种流程图的区别。(设计意图:应用所学知识解决问题是最终目的,通过完成成绩评价系统可以将所学知识应用到实际问题中去,通过思考两种流程图的区别能够提高思维的严密性。)

四、教学反思

本节以设计四则运算器为重点讲了Select语句的基本格式。通 过上节课IF语句的学习,学生对编程思想基本有了一定的了解,因此根据本节内容较多的特点,在授课时除重点对Select语句格式及执行过程详解外,其他内容让学生参照教科书自己完成。并将一些课后内容拿到课堂上来,使一些接受能力强,完成速度快的学生可以“吃得饱”。用任务驱动和小组合作的形式,对能力稍差的同学也可以有所带动。通过课后帮助家长设计薪金所得税程序,使学生对纳税意识有初步了解,增强学生依法纳税道德意识。

第五篇:SQL语句 SELECT LIKE like用法详解

SQL语句 SELECT LIKE like用法详解 在SQL结构化查询语言中,LIKE语句有着至关重

要的作用。LIKE语句的语法格式是:select * from 表名 where 字段名 like 对

应值(子串),它主要是针对字符型字段的,它的作用是在一个字符型字段列中检索包含对

应子串的。A:% 包含零个或多个字符的任意字符串:

1、LIKE'Mc%' 将搜索以字母 Mc 开

头的所有字符串(如 McBadden)。

2、LIKE'%inger' 将搜索以字母 inger 结尾的所有字符

串(如 Ringer、Stringer)。

3、LIKE'%en%' 将搜索在任何位置包含字母 en 的所有字符串

(如 Bennet、Green、McBadden)。B:_(下划线)任何单个字符:LIKE'_heryl' 将搜索以

字母 heryl 结尾的所有六个字母的名称(如 Cheryl、Sheryl)。C:[ ] 指定范围([a-f])或

集合([abcdef])中的任何单个字符: 1,LIKE'[CK]ars[eo]n' 将搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。

2、LIKE'[M-Z]inger' 将搜索以字符串 inger 结

尾、以从 M 到 Z 的任何单个字母开头的所有名称(如 Ringer)。D:[^] 不属于指定范

围([a-f])或集合([abcdef])的任何单个字符:LIKE'M[^c]%' 将搜索以字母 M 开头,并且

第二个字母不是 c 的所有名称(如MacFeather)。E:* 它同于DOS命令中的通配符,代

表多个字符:c*c代表cc,cBc,cbc,cabdfec等多个字符。F:?同于DOS命令中的?通配符,代表单个字符 :b?b代表brb,bFb等 G:# 大致同上,不同的是代只能代表单个数字。k#k

代表k1k,k8k,k0k。F:[!] 排除 它只代表单个字符下面我们来举例说明一下:例

1,查询name字段中包含有“明”字的。select * from table1 where name like '%明%'例2,查询name字段中以“李”字开头。select * from table1 where name like '李*'例3,查询name字段中含有数字的。select * from table1 where name like '%[0-9]%'例4,查询name字段中含有小写字母的。select * from table1 where name like '%[a-z]%'例5,查询name字段中不含有数字的。select * from table1 where name like '%[!0-9]%'以上例子能列出什么值来显而易见。但在这里,我们着重要说明的是通配符“*”与“%”的区别。很多朋友会问,为什么我在以上查询时有个别的表示所有字符的时候用

“%”而不用“*”?先看看下面的例子能分别出现什么结果:select * from table1 where

name like '*明*'select * from table1 where name like '%明%'大家会看到,前

一条语句列出来的是所有的记录,而后一条记录列出来的是name字段中含有“明”的记录,所以说,当我们作字符型字段包含一个子串的查询时最好采用“%”而不用“*”,用“*”的时候只在开头或者只在结尾时,而不能两端全由“*”代替任意字符的情况下。

下载select语句性能优化小结(精选5篇)word格式文档
下载select语句性能优化小结(精选5篇).doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    51CTO下载-50个精妙的select查询语句

    Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题: 1、查询“001”课程比“002”课程成绩高的所有学......

    多分支结构——select语句》教学设计(推荐阅读)

    《多分支结构——select语句》教学设计 一、教材分析 本节课是海南省信息技术九年级上册第二章第三节的内容。前面学生已经了解了visual basic 的工作界面和VB代码,并对流程......

    八年级信息技术《第九讲 Select Case 语句》教案

    第九讲 Select Case 语句 End Select 功能:根据“测试表达式”的值,选择第一个符合条件的语句块执行。 Select Case语句的执行过程是:先求“测试表达式”的值,然后顺序测试该值......

    LoadRunner测试SQL语句性能

    本次通过loadRunner录制SQLServer介绍一下如何测试一个sql语句或存储过程的执行性能。 主要分如下几个步骤完成: 第一步、测试准备 第二步、配置ODBC数据源 第三步、录制SQL......

    计算机系统性能优化总结

    计算机系统性能优化总结 现今,计算机技术在社会各行各业都得到了广泛的应用。计算机给我们的学习、生活和工作都带来了极大的便利。但随着我们对计算机整体性能要求的提高,计......

    网站前端性能优化总结

    一、服务器侧优化 1. 添加 Expires 或 Cache-Control 信息头 某些经常使用到、并且不会经常做改动的图片(banner、logo等等)、静态文件(登录首页、说明文档等)可以设置较长的有......

    锅炉性能试验小结

    培训小结 本次培训内容是电站锅炉燃烧调整、性能试验及运行相关问题的探讨,培训时间2016年11月1日至2日,授课内容主要包括锅炉燃烧调整试验、冷态动力场试验、电站锅炉性能试......

    .Net+SQL Server企业应用性能优化笔记3——SQL查询语句

    在上一篇文章中我们使用了几种方法来确定瓶颈,找到瓶颈,下面再回顾一下: LoadRunner压力测试+Windows计数器,这种方法主要是找出大概的性能问题是在哪台服务器,主要是哪个资源紧......