SqlServer性能优化
1、SQL执行的流程 SqlServer会对每一条执行的指令生成一个执行计划并对执行计划进行缓存plan cache,通常情况下执行同样的SQL下次会直接查找plan进行执行跳过编译的过程。新指令通常的执行流程为“收到执行指令——》plan?cache中找不到(找到则跳过到编译的流程)——》解释(语法、句法)——》编译——》生成执行计划并加入cache——》执行”。 SQL指令的执行方式如下: (1)从缓存的执行计划执行 为了避免资源的浪费提高整体执行的效率SqlServer通常会查找plan cache执行,但执行计划的好坏最终决定了执行的效率缓存的plan并非最好的(这点在优化性能时需注意,某些情况下可能需要手工重建执行计划)。 (2)重编译 有些时候,SqlServer为了确保返回正确的值,或者有性能上的顾虑,有意不重用缓存在内存里的执行计划,而现场编译一份,这种行为,被称为重编译(recompile)。包括如下情况: A、当指令或者批处理所涉及的任何一个对象(表格或者视图)发生了架构(schema)变化 B、运行过sp_recompile C、有些动作会清除内存里的所有执行计划,迫使大家都要做重编译 D、当下面这些SET 开关值变化后,先前的那些执行计划都不能重用 E、当表格或者视图上的统计信息发生变化后 ? 2、执行计划 (1)作用 当我们的系统上线后数据库的记录不断增加,之前写的一些SQL语句或者一些ORM操作效率变得非常低。我们不得不考虑SQL优化,SQL优化大概是这样一个流程: A、定位执行效率低的SQL语句(定位) B、分析为什么这段SQL执行的效率比较低(分析) C、最后根据第二步分析的结构采取优化措施(解决) 执行计划可以告诉我们SQL的执行情况包括SQL如何使用索引、连接查询的执行顺序、查询的数据行数等。 可通过如下语句查看缓存的执行计划 SELECT OBJECT_NAME(objid),sql,* FROM sys.[syscacheobjects] WHERE cacheobjtype=‘Compiled Plan‘ ? (2)显示执行计划的方式 A、SSMS界面进行选择 B、使用快捷键Ctrl+l C、通过SET开关控制 .SHOWPLAN_TEXT?– 显示了一个基本的基于文本的预估执行计划,而不必执行查询。 D、使用SQL Server Profiler E、通过执行计划缓存获取 查看开销大的执行计划: 按平均 CPU 时间检索有关前五个查询的信息 SELECT TOP 5 total_worker_time/execution_count AS [Avg CPU Time],Plan_handle,query_plan FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) ORDER BY total_worker_time/execution_count DESC; GO ? 3、根据执行计划进行优化 ?根据执行计划进行优化主要是去找到开销比较大的块进行分析并优化,关注点包括数据访问的操作方式、读取的数据量大小及是否采用临时表等。数据访问的方式无非是扫描、查找及两者的结合。扫描就是读取整个结构,可以访问一个heap或者一个clustered索引或者一个non-clustered索引,而查找则不会读取整个结构,它则是更高效地通过索引访问一行,所以从这个角度来看,查找就只能应用在索引上面了。 (1)访问操作 以下讲解相关的概念,以表RecognisePhotoBox为例: CREATE TABLE [dbo].[RecognisePhotoBox] ( [BoxId] [bigint] NOT NULL IDENTITY(1,1),[VenderId] [int] NOT NULL,[PhotoId] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL,[SkuCode] [int] NOT NULL ) ALTER TABLE [dbo].[RecognisePhotoBox] ADD CONSTRAINT [PK_RECOGNISEPHOTOBOX] PRIMARY KEY CLUSTERED ([BoxId]) CREATE NONCLUSTERED INDEX [nci_RecognisePhotoBox_PhotoId_VenderId] ON [dbo].[RecognisePhotoBox] ([PhotoId],[VenderId]) A、表扫描 效率最低,大数据表尽量避免使用(临时表也一样需要建索引) B、Clustered Index扫描 C、non-Clustered Index扫描 D、Clustered Index查找 ? E、non-Clustered Index查找 F、书签查询 如下SkuCode没有在非聚集索引中,先会去non-Clustered Index查找一次,然后去Lookup前面查找结果对应的数据表记录。 书签查询可通过Include索引(在索引中包括其它要查找的字段)等进行优化 CREATE NONCLUSTERED INDEX [nci_RecognisePhotoBox_PhotoId_VenderId] ON [dbo].[RecognisePhotoBox] ([PhotoId],[VenderId]) INCLUDE(SkuCode) 注意:执行计划里用来估计的信息来源于“数据库统计信息”,如?estimated number of? rows ? 4、索引的重要性 ?索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。索引分为聚集索引与非聚集索引,聚集索引表示表中存储的数据按照索引的顺序存储,非聚集索引表示数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。 (1)索引优点 A、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。? (2)索引缺点 A、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。? (3)查询索引的层级结构及占用空间了解索引 --查询索引信息 Select id.name,p.index_level,p.page_count,p.index_id,avg_record_size_in_bytes,max_record_size_in_bytes,min_record_size_in_bytes from sys.dm_db_index_physical_stats(DB_ID(‘EXEU_TEST_MARK‘),Object_id(‘RecognisePhotoBox‘),null,‘Detailed‘) as p Inner Join sys.indexes as id On p.index_id = id.index_id And p.object_id = id.object_id And p.index_id > 1 其中Index_Level为0的表示索引的叶级,为1、2的表示索引的非叶级 ? 5、复杂存储过程的优化 (1)找到生成的执行计划 SELECT OBJECT_NAME(dm_exec_query_plan.objectid),UseCounts,Cacheobjtype,Objtype,TEXT,query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) CROSS APPLY sys.dm_exec_query_plan(plan_handle) WHERE objtype=‘Proc‘ AND OBJECT_NAME(dm_exec_query_plan.objectid)=‘pr_createRecogniseCheckBill‘ 右击query_plan的值另存为,文件的后缀填写“.sqlplan”,保存先用记事本或其它编辑工具打开增加“XML声明” 然后双击在SqlServer打开就可看到执行计划图了 ? (2)?找到开销大的查询 此处大数据量的临时表走了表扫描 需要给临时表创建索引 CREATE INDEX tidx_1 ON #temp_boxNoStitch(PhotoId) CREATE INDEX tidx_2 ON #temp_scaletable(PhotoId) INCLUDE(rowno,IsStitch) ? 6、大数据量优化的注意事项 (1)sp_executesql的效率非常低,用exec替换sp_executesql (2)需在上下文多次使用的大数据关联表结果,采用临时表保存,并根据查询条件对临时表建索引 (3)建索引时需要去掉冗余度太高的字段当索引,可放到索引包含列include里 ? 参考: 【MySQL】SQL执行计划分析 ?https://blog.csdn.net/da_guo_li/article/details/79008016 SQL Server执行计划详细介绍(一) https://cloud.tencent.com/developer/news/254038 SQLSERVER编译与重编译 https://www.cnblogs.com/lyhabc/archive/2013/01/17/2865290.html SQL查询性能优化----解决书签查找 https://www.2cto.com/database/201208/146201.html 数据库索引的作用优点和缺点 https://blog.csdn.net/u013310119/article/details/52527632 对SQL Server索引包含列(Include)的一点认识 https://blog.csdn.net/zhengldg/article/details/9128723 如何获得查询的执行计划?(一) http://bbs.51cto.com/thread-1317501-1.html sys.dm_exec_query_plan (Transact-SQL) https://docs.microsoft.com/zh-cn/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-query-plan-transact-sql?view=sql-server-2017 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |