SQL性能优化的几个思路(二)

最近又总结了一批SQL性能优化的方法,大家可以参照着做。前一次的优化思路在这里:

SQL性能优化的几个思路


1、WHERE、JOIN的字段,能用主表字段就用主表字段,比如下面这样:

SELECT *
FROM A --主表
    INNER JOIN B ON A.ID=B.ID
    INNER JOIN C ON B.ID=C.ID--注意这里
WHERE B.ID=1023--注意这里

这时的优化方法有:

A、把关联C表时用的B.ID换成A.ID;

B、把WHERE条件中的B.ID换成A.ID

这个情况我不太清楚具体原理,最近在优化一条语句的时候,发现怎么优化都没用。突然发了神经,把关联字段全部换成了主表字段,结果速度一下子就上来了

2、减少中间表数据提取

SELECT * FROM (
    SELECT * 
    FROM A 
        INNER JOIN B ON A.ID=B.ID
    ) AS AB 
WHERE AB.BMONTH=202312 AND 其他条件

SELECT * FROM (
    SELECT * 
    FROM A 
        INNER JOIN B ON A.ID=B.ID 
    WHERE A.BMONTH=202312) AS AB 
WHERE 其他条件

看看这两条语句,觉得哪条性能高?

当然是第二条。

这两个语句都分为两步,第一步是以A、B表作关联,生成一个中间表,然后再从中间表取数据。

第一条语句直接用A关联B,把所有数据都提取出来,涉及的数据量自然很大。

第二条语句把查询条件A.BMONTH加到中间表中,中间表提取的数据量就大为减少,这时对于内存的消耗会急剧减少。


3、减少涉及数据量的提取
看一个分页算法:

SELECT * 
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY ID) ROWNUM,* 
    FROM A) A1
WHERE A.ROWNUM BETWEEN 1 AND 100


SELECT * 
INTO #TEMP
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY ID) ROWNUM,ID  
    FROM A  ) AS A1
WHERE A.ROWNUM BETWEEN 1 AND 100
SELECT * 
FROM #TEMP 
    INNER JOIN A ON A.ID=#TEMP.ID

请问哪个性能更强?

在A表中字段不多的时候,其实性能差不了多少,但是当A表字段多(比如有20个)且有多张表格关联的时候,后者的优势就显示出来了。

前者是把A表中符合条件的记录全部提取到内存里面作分页,涉及的数据量是A表所有字段和所有数据

后者是只提取符合条件的100条记录的ID和行号,然后再去关联A表,涉及的数据量就那么一点,速度肯定更快
 

4、适度删除部分索引

A表有以下字段:

CREATETIME,创建时间

STATE,状态,取值0、1、2

FACTORYCODE,厂家编号,取值少于10个

DATAVALUE,读取数据值

建立的索引有:

FACTORYCODE+STATE的联合索引

CREATETIME索引

DATAVALUE索引

DATAVALUE+STATE索引

实际分析情况:

FACTORYCODE、STATE的可取值太少,建立索引的意义不大,可以把这两个字段上的索引全部删除

DATAVALUE一般用于统计汇总,而且也不会加入到GROUP和WHERE子句里面,存在意义不大,可以删除

只有CREATETIME可能是经常会被加入查询条件的,应该保留

索引影响的主要功能点有这几个:

A、插入、修改、删除数据时,可能会引起索引的重排,这时对这些功能有部分影响,所以很多同行都在强调要尽量少建索引

B、索引的原理是排序,当一个字段上的可选值很少时,即使作了排序也没多少意义,所以对于可选值少的字段一般不建立索引

5、使用SQLBULKCOPY作批量数据插入

看下面几行代码:

DataTable dt=new DataTable()
//此处可以加一些数据列与行
using (var copy = new SqlBulkCopy(con))//con即数据库连接
{
    copy.DestinationTableName = "MyTest";//MyTest是用于测试的表名
    copy.WriteToServer(dt);
}

插入数据的方法一般就是单条插入、多条语句组装插入,在1000条以下时,SQLBULKCOPY能够使速度提升20倍左右;在达到10000条以上时,一般能够提升40倍左右。所以如果有大批量数据插入的需求,可以考虑用SQLBULKCOPY来替代INSERT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬瓜就是我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值