问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

T-SQL语句,谁能帮我优化一下?

发布网友 发布时间:2022-05-01 00:13

我来回答

2个回答

懂视网 时间:2022-05-01 04:35

Select A.ID, A.col1, B.col2 -- Select A.ID, col1, col2 –不要这么写,不利于将来程序扩展 from table1 A inner join table2 B on A.ID=B.ID Where … B、纵向来看, (1)合理写WHERE子句,不要写没有WHERE的SQL语句。 (2) SELECT TOP N * --没有WHERE条件的用此替代

四 :尽量少做重复的工作

A、控制同一语句的多次执行,特别是一些基础数据的多次执行是很多程序员很少注意的。

B、减少多次的数据转换,也许需要数据转换是设计的问题,但是减少次数是程序员可以做到的。

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

D、合并对同一表同一条件的多次UPDATE,比如

UPDATE EMPLOYEE SET FNAME=‘HAIWER‘
WHERE EMP_ID=‘ VPA30890F‘ UPDATE EMPLOYEE SET LNAME=‘YANG‘
WHERE EMP_ID=‘ VPA30890F‘
这两个语句应该合并成以下一个语句
UPDATE EMPLOYEE SET FNAME=‘HAIWER‘,LNAME=‘YANG‘ WHERE EMP_ID=‘ VPA30890F‘

E、UPDATE操作不要拆成DELETE操作+INSERT操作的形式,虽然功能相同,但是性能差别是很大的。

五、注意临时表和表变量的用法

在复杂系统中,临时表和表变量很难避免,关于临时表和表变量的用法,需要注意:

A、如果语句很复杂,连接太多,可以考虑用临时表和表变量分步完成。

B、如果需要多次用到一个大表的同一部分数据,考虑用临时表和表变量暂存这部分数据。

C、如果需要综合多个表的数据,形成一个结果,可以考虑用临时表和表变量分步汇总这多个表的数据。

D、其他情况下,应该控制临时表和表变量的使用。

E、关于临时表和表变量的选择,很多说法是表变量在内存,速度快,应该首选表变量,但是在实际使用中发现,

(1)主要考虑需要放在临时表的数据量,在数据量较多的情况下,临时表的速度反而更快。

(2)执行时间段与预计执行时间(多长)

F、关于临时表产生使用SELECT INTO和CREATE TABLE + INSERT INTO的选择,一般情况下,

SELECT INTO会比CREATE TABLE + INSERT INTO的方法快很多,

但是SELECT INTO会锁定TEMPDB的系统表SYSOBJECTS、SYSINDEXES、SYSCOLUMNS,在多用户并发环境下,容易阻塞其他进程,

所以我的建议是,在并发系统中,尽量使用CREATE TABLE + INSERT INTO,而大数据量的单个语句使用中,使用SELECT INTO。

六、子查询的用法(1)

  子查询是一个 SELECT 查询,它嵌套在 SELECT、INSERT、UPDATE、DELETE 语句或其它子查询中。

任何允许使用表达式的地方都可以使用子查询,子查询可以使我们的编程灵活多样,可以用来实现一些特殊的功能。但是在性能上,

往往一个不合适的子查询用法会形成一个性能瓶颈。如果子查询的条件中使用了其外层的表的字段,这种子查询就叫作相关子查询。

相关子查询可以用IN、NOT IN、EXISTS、NOT EXISTS引入。 关于相关子查询,应该注意:

(1)

A、NOT IN、NOT EXISTS的相关子查询可以改用LEFT JOIN代替写法。比如: SELECT PUB_NAME FROM PUBLISHERS WHERE PUB_ID NOT IN (SELECT PUB_ID FROM TITLES WHERE TYPE = ‘BUSINESS‘) 可以改写成: SELECT A.PUB_NAME FROM PUBLISHERS A LEFT JOIN TITLES B ON B.TYPE = ‘BUSINESS‘ AND A.PUB_ID=B. PUB_ID WHERE B.PUB_ID IS NULL

(2)

SELECT TITLE FROM TITLES 
WHERE NOT EXISTS 
 (SELECT TITLE_ID FROM SALES 
WHERE TITLE_ID = TITLES.TITLE_ID)
可以改写成:
SELECT TITLE 
FROM TITLES LEFT JOIN SALES 
ON SALES.TITLE_ID = TITLES.TITLE_ID 
WHERE SALES.TITLE_ID IS NULL
B、 如果保证子查询没有重复 ,IN、EXISTS的相关子查询可以用INNER JOIN 代替。比如:
SELECT PUB_NAME 
FROM PUBLISHERS 
WHERE PUB_ID IN
 (SELECT PUB_ID 
 FROM TITLES 
 WHERE TYPE = ‘BUSINESS‘)
可以改写成:
SELECT A.PUB_NAME --SELECT DISTINCT A.PUB_NAME 
FROM PUBLISHERS A INNER JOIN TITLES B 
ON B.TYPE = ‘BUSINESS‘ AND
A.PUB_ID=B. PUB_ID

(3)

C、 IN的相关子查询用EXISTS代替,比如
SELECT PUB_NAME FROM PUBLISHERS 
WHERE PUB_ID IN
(SELECT PUB_ID FROM TITLES WHERE TYPE = ‘BUSINESS‘)
可以用下面语句代替:
SELECT PUB_NAME FROM PUBLISHERS WHERE EXISTS 
(SELECT 1 FROM TITLES WHERE TYPE = ‘BUSINESS‘ AND
PUB_ID= PUBLISHERS.PUB_ID)
D、不要用COUNT(*)的子查询判断是否存在记录,最好用LEFT JOIN或者EXISTS,比如有人写这样的语句:
SELECT JOB_DESC FROM JOBS 
WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)=0
应该改成:
SELECT JOBS.JOB_DESC FROM JOBS LEFT JOIN EMPLOYEE 
ON EMPLOYEE.JOB_ID=JOBS.JOB_ID 
WHERE EMPLOYEE.EMP_ID IS NULL
 
SELECT JOB_DESC FROM JOBS 
WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)<>0
应该改成:
SELECT JOB_DESC FROM JOBS 
WHERE EXISTS (SELECT 1 FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID) 

七:尽量使用索引

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

索引的选择和使用方法是SQLSERVER的优化器自动作的选择,而它选择的根据是查询语句的条件以及相关表的统计信息,这就要求我们在写SQL

语句的时候尽量使得优化器可以使用索引。为了使得优化器能高效使用索引,写语句的时候应该注意:

(1

A、不要对索引字段进行运算,而要想办法做变换,比如
 SELECT ID FROM T WHERE NUM/2=100
 应改为:
 SELECT ID FROM T WHERE NUM=100*2
 
 SELECT ID FROM T WHERE NUM/2=NUM1
 如果NUM有索引应改为:
 SELECT ID FROM T WHERE NUM=NUM1*2
 如果NUM1有索引则不应该改。

(2)

发现过这样的语句:
 SELECT 年,月,金额 FROM 结余表 WHERE 100*年+月=2010*100+10
 应该改为:
 SELECT 年,月,金额 FROM 结余表 WHERE 年=2010 AND月=10
 
B、 不要对索引字段进行格式转换
日期字段的例子:
WHERE CONVERT(VARCHAR(10), 日期字段,120)=‘2010-07-15‘
应该改为
WHERE日期字段〉=‘2010-07-15‘ AND 日期字段<‘2010-07-16‘
 
ISNULL转换的例子:
WHERE ISNULL(字段,‘‘)<>‘‘应改为:WHERE字段<>‘‘
WHERE ISNULL(字段,‘‘)=‘‘不应修改
WHERE ISNULL(字段,‘F‘) =‘T‘应改为: WHERE字段=‘T‘
WHERE ISNULL(字段,‘F‘)<>‘T‘不应修改

(3)

C、 不要对索引字段使用函数
WHERE LEFT(NAME, 3)=‘ABC‘ 或者WHERE SUBSTRING(NAME,1, 3)=‘ABC‘
应改为: WHERE NAME LIKE ‘ABC%‘
日期查询的例子:
WHERE DATEDIFF(DAY, 日期,‘2010-06-30‘)=0
应改为:WHERE 日期>=‘2010-06-30‘ AND 日期 <‘2010-07-01‘
WHERE DATEDIFF(DAY, 日期,‘2010-06-30‘)>0
应改为:WHERE 日期 <‘2010-06-30‘
WHERE DATEDIFF(DAY, 日期,‘2010-06-30‘)>=0
应改为:WHERE 日期 <‘2010-07-01‘
WHERE DATEDIFF(DAY, 日期,‘2010-06-30‘)<0
应改为:WHERE 日期>=‘2010-07-01‘
WHERE DATEDIFF(DAY, 日期,‘2010-06-30‘)<=0
应改为:WHERE 日期>=‘2010-06-30‘

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

  比如:

  WHERE FAME+ ‘. ‘+LNAME=‘HAIWEI.YANG‘

  应改为:

  WHERE FNAME=‘HAIWEI‘ AND LNAME=‘YANG‘

  

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

  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、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数

B、注意UNION和UNION ALL的区别。--允许重复数据用UNION ALL好  

C、注意使用DISTINCT,在没有必要时不要用

 D、TRUNCATE TABLE 与 DELETE 区别

 E、减少访问数据库的次数

还有就是我们写存储过程,如果比较长的话,最后用标记符标开,因为这样可读性很好,即使语句写的不怎么样但是语句工整,C# 有region

sql我比较喜欢用的就是

--startof 查询在职人数
 sql语句
 --end of

    正式机器上我们一般不能随便调试程序,但是很多时候程序在我们本机上没问题,但是进正式系统就有问题,但是我们又不能随便在正式机器上操作,那么怎么办呢?我们可以用回滚来调试我们的存储过程或者是sql语句,从而排错。

BEGIN TRAN
 UPDATE a SET 字段=‘‘
ROLLBACK

作业存储过程我一般会加上下面这段,这样检查错误可以放在存储过程,如果执行错误回滚操作,但是如果程序里面已经有了事务回滚,那么存储过程就不要写事务了,这样会导致事务回滚嵌套降低执行效率,但是我们很多时候可以把检查放在存储过程里,这样有利于我们解读这个存储过程,和排错。

BEGIN TRANSACTION 
--事务回滚开始 
 
--检查报错
 IF ( @@ERROR > 0 ) 
   BEGIN 
--回滚操作
   ROLLBACK TRANSACTION 
   RAISERROR(‘删除工作报告错误‘, 16, 3) 
   RETURN  
   END  
 
 
--结束事务
 COMMIT TRANSACTION 

 

T-SQL优化

标签:

热心网友 时间:2022-05-01 01:43

select a.MonthKey, a.BUKey
    , sum(a.[NetRev]) as NetRev
    , sum(a.[DirectCost]) as DirectCost
into #tmp_FactRevenue_mksummary
from [dbo].[FactRevenue] a
where MonthKey between @StartDate and @EndDate
group by a.MonthKey, a.BUKey

SELECT Category, 
    d.[MonthName],d.MonthKey, BUKey,
    egg
INTO #111 
FROM (

    select 'Revenue' as Category
        , d.MonthKey, a.BUKey
        , NetRev as egg
    from #tmp_FactRevenue_mksummary

    union all

    select 'Director Cost / PGM%' as Category
        , d.MonthKey, a.BUKey
        , DirectCost as egg
    from #tmp_FactRevenue_mksummary

    union all

    SELECT 'Indirect Cost' as Category,
        a.MonthKey,a.BUKey,
        sum(a.[NetExpense]) as NetExpense
    FROM [FinanceBIDW].[dbo].[FactDepex] a
    where MonthKey between @StartDate and @EndDate
    and exists (select 1 
        from DimCCC b 
        where b.CCCKey=a.CCCKey
        and b.Category='cost'
        )
    group by a.MonthKey,a.BUKey

)T1
join [dbo].[DimMonth] d on T1.MonthKey=d.MonthKey

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
amd锐龙r75700g超频性价比装机方案,要核显性能综合表现超 架空电线故障如何排除 ...unexpected T_CONSTANT_ENCAPSED_STRING in 怎么解决这个错啊_百度... php错误Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_S... PHP出现如下情况 syntax error, unexpected T_ENCAPSED_AND_WHITES... php 如何捕获类似于Parse error: syntax error, unexpected T_CONSTA... 挂烫机如何熨西装 戗驳领西装怎么熨烫 西装前片怎么推拉拔烫 西装能不能拿去烫 微信公众账号订阅号的名称和在认证的时候可以改吗? win7雨滴(rainmeter)怎么隐藏桌面图标,就是把(我的电脑,英雄联盟等桌面图标)隐藏达到图中效果!! 求罪恶王冠的雨滴桌面秀素材~! 大侠,我在别人的提问上看到你的win7黑岩射手主题,雨滴桌面秀的那个,能教教我么?多谢! 求一份雨滴桌面秀主题,win7系统使用,模拟win10画面风格的主题皮肤包 谁能搞到雨滴桌面钢铁侠蜂窝桌面主题,Win7 64位的 win7雨滴桌面软件教程 麻烦要具体版的 如果很具体 正确 我还会追加分的。。。麻烦把教程 和软件都发到这个 下载的雨滴桌面怎么用,求大神详细讲解 在闲鱼上买家付款,卖家发货但物流不走超过了时间会打钱给卖家吗? 求WIN7罪恶王冠主题+雨滴桌面和插件,急急急- -好的话加分 闲鱼卖家可以发地址给我吗 闲鱼卖家不按收货详细地址发货怎么办? windows7怎么设置动态桌面,比如桌面一直是下雨,水滴在动 闲鱼卖家退货地址不属实 求win7雨滴桌面和主题,最好告诉一下怎么装,谢了! 闲鱼退货地址发出来,可是卖家故意拖延不给发货,怎么办 Win7雨滴桌面桌面做? 刚装好WINDOWS7系统时的水滴桌面不在了?怎么找回来?怎么设置? 个人订阅号认证之的时候可以更改公众号的昵称么? 微信公众号订阅号个人的,账号名称确定后,还能修改么 深圳市顺丰快递公司机场普工在哪里招聘 龙华顺丰快递公司招聘快递员吗? 深圳顺丰公司招快递员吗?有什么条件? 在深圳做快递员,有什么条件吗?都需要什么? 深圳宝安区顺丰快递现在招聘快递员吗? 想在深圳做顺丰的快递员,没看到哪里有招聘的信息,有信息的人可否指点下,谢谢! 我想去深圳顺丰快递做收派员,那位前辈知道去哪个人才市场在招聘? 变形金刚里的十三使徒很神秘,你知道是哪几位吗? 支付宝网商银行怎么开通 支付宝的网商银行没十八可以开吗? 贼开心软件在哪下 贼开心什么意思? 变形金刚领袖之证红蜘蛛握着黑暗超能量体的图片,快!我忘了是地几集了,你们帮我截图吧。 开心网 开心城市怎么抓小偷啊?是系统自动的吗? 开心网问题 开心网 开心农场攻略 “知识”这个词我知道是什么意思,“知”与“识”分开来看,它们是什么意思? 开心网仓库打不开 开心网的牧场要怎么偷东东? 知识的含义是什么?