如何进行SQL性能优化

如何进行SQL性能优化,第1张

进行SQL性能优化的方法:

1、SQL语句不要写的太复杂。一个SQL语句要尽量简单,不要嵌套太多层。

2、使用『临时表』缓存中间结果。简化SQL语句的重要方法就是采用临时表暂存中间结果,这样可以避免程序中多次扫描主表,也大大减少了阻塞,提高了并发性能。

3、使用like的时候要注意是否会导致全表扫,有的时候会需要进行一些模糊查询例如:select id from table where username like ‘%hollis%’关键词%hollis%,由于hollis前面用到了“%”,因此该查询会使用全表扫描,除非必要,否则不要在关键词前加%。

4、尽量避免使用!=或<> *** 作符。在where语句中使用!=或<>,引擎将放弃使用索引而进行全表扫描。

5、尽量避免使用 or 来连接条件;在 where 子句中使用 or 来连接条件,引擎将放弃使用索引而进行全表扫描。可以使用

select id from t where num=10

union all

select id from t where num=20

替代

select id from t where num=10 or num=20

6、尽量避免使用in和not in:在 where 子句中使用 in和not in,引擎将放弃使用索引而进行全表扫描。可以使用

select id from t where num between 10 and 20

替代

select id from t where num in (10,20)

7、可以考虑强制查询使用索引

select * from table force index(PRI) limit 2(强制使用主键)

select * from table force index(hollis_index) limit 2(强制使用索引"hollis_index")

select * from table force index(PRI,hollis_index) limit 2(强制使用索引"PRI和hollis_index")

8、尽量避免使用表达式、函数等 *** 作作为查询条件;尽量避免大事务 *** 作,提高系统并发能力。尽量避免使用游标;任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

9、尽可能的使用 varchar/nvarchar 代替 char/nchar。尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。

10、索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引。

一段SQL代码写好以后,可以通过查看SQL的执行计划,初步预测该SQL在运行时的性能好坏,尤其是在发现某个SQL语句的效率较差时,我们可以通过查看执行计划,分析出该SQL代码的问题所在。

1、 打开熟悉的查看工具:PL/SQL Developer。

在PL/SQL Developer中写好一段SQL代码后,按F5,PL/SQL Developer会自动打开执行计划窗口,显示该SQL的执行计划。

2、 查看总COST,获得资源耗费的总体印象

一般而言,执行计划第一行所对应的COST(即成本耗费)值,反应了运行这段SQL的总体估计成本,单看这个总成本没有实际意义,但可以拿它与相同逻辑不同执行计划的SQL的总体COST进行比较,通常COST低的执行计划要好一些。

3、 按照从左至右,从上至下的方法,了解执行计划的执行步骤

执行计划按照层次逐步缩进,从左至右看,缩进最多的那一步,最先执行,如果缩进量相同,则按照从上而下的方法判断执行顺序,可粗略认为上面的步骤优先执行。每一个执行步骤都有对应的COST,可从单步COST的高低,以及单步的估计结果集(对应ROWS/基数),来分析表的访问方式,连接顺序以及连接方式是否合理。

4、 分析表的访问方式

表的访问方式主要是两种:全表扫描(TABLE ACCESS FULL)和索引扫描(INDEX SCAN),如果表上存在选择性很好的索引,却走了全表扫描,而且是大表的全表扫描,就说明表的访问方式可能存在问题;若大表上没有合适的索引而走了全表扫描,就需要分析能否建立索引,或者是否能选择更合适的表连接方式和连接顺序以提高效率。

5、 分析表的连接方式和连接顺序

表的连接顺序:就是以哪张表作为驱动表来连接其他表的先后访问顺序。

表的连接方式:简单来讲,就是两个表获得满足条件的数据时的连接过程。主要有三种表连接方式,嵌套循环(NESTED LOOPS)、哈希连接(HASH JOIN)和排序-合并连接(SORT MERGE JOIN)。我们常见得是嵌套循环和哈希连接。

嵌套循环:最适用也是最简单的连接方式。类似于用两层循环处理两个游标,外层游标称作驱动表,Oracle检索驱动表的数据,一条一条的代入内层游标,查找满足WHERE条件的所有数据,因此内层游标表中可用索引的选择性越好,嵌套循环连接的性能就越高。

哈希连接:先将驱动表的数据按照条件字段以散列的方式放入内存,然后在内存中匹配满足条件的行。哈希连接需要有合适的内存,而且必须在CBO优化模式下,连接两表的WHERE条件有等号的情况下才可以使用。哈希连接在表的数据量较大,表中没有合适的索引可用时比嵌套循环的效率要高。

sql server性能分析--查看表数据页数

返回表名、索引名和行数

SELECT object_name(i.object_id) as objectName, i.[name] as indexName, sum(p.rows) as rowCnt

FROM sys.indexes i

INNER JOIN sys.partitions p

ON i.object_id = p.object_id

AND i.index_id = p.index_id

WHERE i.object_id = object_id('dbo.Meeting')

AND i.index_id <= 1

GROUP BY i.object_id, i.index_id, i.[name]

返回表的总页数、使用页数、数据页数

SELECT object_name(i.object_id) as objectName, i.[name] as indexName,

sum(a.total_pages) as totalPages, sum(a.used_pages) as usedPages, sum(a.data_pages) as dataPages,

(sum(a.total_pages) * 8) / 1024 as totalSpaceMB, (sum(a.used_pages) * 8) / 1024 as usedSpaceMB,

(sum(a.data_pages) * 8) / 1024 as dataSpaceMB

FROM sys.indexes i

INNER JOIN sys.partitions p

ON i.object_id = p.object_id

AND i.index_id = p.index_id

INNER JOIN sys.allocation_units a

ON p.partition_id = a.container_id

WHERE i.object_id = object_id('dbo.Meeting')

AND i.index_id <= 1

GROUP BY i.object_id, i.index_id, i.[name]

按页类型分类统计

SELECT case when grouping(i.object_id) = 1 then '--- TOTAL ---' else object_name(i.object_id) end as objectName,

case when grouping(i.[name]) = 1 then '--- TOTAL ---' else i.[name] end as indexName,

case when grouping(a.type_desc) = 1 then '--- TOTAL ---' else a.type_desc end as pageType,

sum(a.total_pages) as totalPages, sum(a.used_pages) as usedPages, sum(a.data_pages) as dataPages,

(sum(a.total_pages)

* 8) / 1024 as totalSpaceMB, (sum(a.used_pages) * 8) / 1024 as

usedSpaceMB, (sum(a.data_pages) * 8) / 1024 as dataSpaceMB

FROM sys.indexes i

INNER JOIN sys.partitions p

ON i.object_id = p.object_id

AND i.index_id = p.index_id

INNER JOIN sys.allocation_units a

ON p.partition_id = a.container_id

WHERE i.object_id = object_id('dbo.Meeting')

AND i.index_id <= 1

GROUP BY i.object_id, i.[name], a.type_desc with rollup


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/10871903.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-11
下一篇2023-05-11

发表评论

登录后才能评论

评论列表(0条)

    保存