MSSQL 技巧系列之三整体优化 中讯汉杨:微软电信项目组 向翔
Top with Ties 选项 <ul><li>select top 100  </li></ul><ul><li>with ties  </li></ul><ul><li>name, </li></ul><ul><li>id  </li><...
MSSQL 处理语句步骤 <ul><li>Select  语句步骤: </li></ul><ul><li>Select  </li></ul><ul><li>Distinct </li></ul><ul><li>top 1 </li></ul>...
推演的部分问题 <ul><li>在 select  列表没有处理以前,是不可以使用字段别名的 </li></ul><ul><li>On 条件的应用在外连接的情况下并不是最终的结果,而需应用 where 筛选内连接的话是没有添加外部行这个步骤,所...
子查询 <ul><li>独立子查询和相关子查询 </li></ul><ul><li>跟外部查询没有关系的查询叫独立子查询,通常只会查询一次 </li></ul><ul><li>相关子查询与外部查询关联,通常需要每行查询 </li></ul>
子查询 <ul><li>标量子查询和多值子查询 </li></ul><ul><li>结果只有一个值的子查询叫标量子查询 </li></ul><ul><li>结果含有多个的叫多值子查询,一般在需要返回一个表的时候才能用到多值子查询 </li></ul>
表垂直连接 <ul><li>Union & Union All </li></ul><ul><li>EXCEPT  </li></ul><ul><li>INTERSECT  </li></ul>
CTE 递归处理 <ul><li>with empcte as  </li></ul><ul><li>( </li></ul><ul><li>select employeeid,reportsto,firstname,lastname </li...
连接三种方式对比
Loop join 最佳索引 <ul><li>没有索引 < </li></ul><ul><li>非聚集非覆盖索引 < </li></ul><ul><li>聚集索引 < </li></ul><ul><li>非聚集覆盖索引 < </li></ul>...
分类前 N 名问题解决 <ul><li>CREATE TABLE table1 ( [ID] [bigint] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](128) NOT NULL, [class] i...
数据库整体优化 <ul><li>整体优化是一个很大的话题,在这里我只是从某些角度来阐述可能出现的一些问题,以及优化的思路。包括编译计划,是否每次都会引起重编译,数据库 IO 压力分析,索引利用率分析, CPU 与代码分析,拙劣执行计划分析等。至...
存储过程编译计划的命中率,以及执行频率 SELECT cacheobjtype, usecounts as Count, cast(C.sql as varChar(max)) as StoredProcedure FROM Master.db...
服务器整体数据库 IO 压力分析 <ul><li>WITH DBIO AS </li></ul><ul><li>( </li></ul><ul><li>SELECT </li></ul><ul><li>DB_NAME(IVFS.database...
索引利用率分析 <ul><li>select b.name,a.* from sys.dm_db_index_usage_stats a inner join sysindexes b </li></ul><ul><li>on (a.objec...
CPU 耗时分析 <ul><li>SELECT </li></ul><ul><li>total_cpu_time, </li></ul><ul><li>total_execution_count, </li></ul><ul><li>total...
总体分析执行计划 <ul><li>CREATE PROCEDURE LookForPhysicalOps (@op VARCHAR(30)) </li></ul><ul><li>AS </li></ul><ul><li>SELECT sql.t...
Upcoming SlideShare
Loading in …5
×

Sql Server 高级技巧系列之三整体优化

845
-1

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
845
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Sql Server 高级技巧系列之三整体优化

  1. 1. MSSQL 技巧系列之三整体优化 中讯汉杨:微软电信项目组 向翔
  2. 2. Top with Ties 选项 <ul><li>select top 100 </li></ul><ul><li>with ties </li></ul><ul><li>name, </li></ul><ul><li>id </li></ul><ul><li>from test1 </li></ul><ul><li>order by name desc </li></ul><ul><li>& select top 100 </li></ul><ul><li>name, </li></ul><ul><li>id </li></ul><ul><li>from test1 </li></ul><ul><li>order by name desc </li></ul><ul><li>上一个语句只会显示出所有包含 name 的行,不管有没有超过 100 的限制。 With ties 的任务是将绑定的字段全部行显示出来。 </li></ul>
  3. 3. MSSQL 处理语句步骤 <ul><li>Select 语句步骤: </li></ul><ul><li>Select </li></ul><ul><li>Distinct </li></ul><ul><li>top 1 </li></ul><ul><li>id,name </li></ul><ul><li>from lefttable l </li></ul><ul><li>inner Join righttable r on i.id=r.id </li></ul><ul><li>Where r.id >100 </li></ul><ul><li>Group by department </li></ul><ul><li>With (cube) </li></ul><ul><li>Having </li></ul><ul><li>Order by r.id </li></ul>对两个表进行笛卡尔积计算交叉连接 应用 on 筛选器,过滤不符合条件的俄行,然后如果是外连接,则将后添加外部行 再对当前虚拟表进行条件筛选 对虚拟表进行分组 生成超组虚拟表 对 group 后的表进行再筛选 处理 select 列表 重复行移除 排序 返回指定数量行
  4. 4. 推演的部分问题 <ul><li>在 select 列表没有处理以前,是不可以使用字段别名的 </li></ul><ul><li>On 条件的应用在外连接的情况下并不是最终的结果,而需应用 where 筛选内连接的话是没有添加外部行这个步骤,所以条件在 on 或者 where 处处理都会得到一样的结果 </li></ul><ul><li>Where 条件不能应用 group 条件,因为他在分组以前就被处理了 </li></ul>
  5. 5. 子查询 <ul><li>独立子查询和相关子查询 </li></ul><ul><li>跟外部查询没有关系的查询叫独立子查询,通常只会查询一次 </li></ul><ul><li>相关子查询与外部查询关联,通常需要每行查询 </li></ul>
  6. 6. 子查询 <ul><li>标量子查询和多值子查询 </li></ul><ul><li>结果只有一个值的子查询叫标量子查询 </li></ul><ul><li>结果含有多个的叫多值子查询,一般在需要返回一个表的时候才能用到多值子查询 </li></ul>
  7. 7. 表垂直连接 <ul><li>Union & Union All </li></ul><ul><li>EXCEPT </li></ul><ul><li>INTERSECT </li></ul>
  8. 8. CTE 递归处理 <ul><li>with empcte as </li></ul><ul><li>( </li></ul><ul><li>select employeeid,reportsto,firstname,lastname </li></ul><ul><li>from dbo.employees </li></ul><ul><li>where employeeid = 2 </li></ul><ul><li>union all </li></ul><ul><li>select emp.employeeid,emp.reportsto,emp.firstname,emp.lastname </li></ul><ul><li>from empcte as mgr </li></ul><ul><li>join dbo.employees as emp </li></ul><ul><li>on emp.reportsto = mgr.employeeid </li></ul><ul><li>) </li></ul><ul><li>select * from empcte option(maxrecursion 2) </li></ul><ul><li>为防止递归出现死套,可以指定递归级别,默认为 100. </li></ul>
  9. 9. 连接三种方式对比
  10. 10. Loop join 最佳索引 <ul><li>没有索引 < </li></ul><ul><li>非聚集非覆盖索引 < </li></ul><ul><li>聚集索引 < </li></ul><ul><li>非聚集覆盖索引 < </li></ul><ul><li>包含非键列的非聚集覆盖索引 </li></ul>
  11. 11. 分类前 N 名问题解决 <ul><li>CREATE TABLE table1 ( [ID] [bigint] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](128) NOT NULL, [class] int not null, [date] datetime not null ) </li></ul><ul><li>select id,name,class,date from( select id,name,class,date ,row_number() over(partition by class order by date desc) as rowindex from table1) a where rowindex <= 5 </li></ul>
  12. 12. 数据库整体优化 <ul><li>整体优化是一个很大的话题,在这里我只是从某些角度来阐述可能出现的一些问题,以及优化的思路。包括编译计划,是否每次都会引起重编译,数据库 IO 压力分析,索引利用率分析, CPU 与代码分析,拙劣执行计划分析等。至于使用 perfmon 调优,可以参看另一个 ppt 。 </li></ul>
  13. 13. 存储过程编译计划的命中率,以及执行频率 SELECT cacheobjtype, usecounts as Count, cast(C.sql as varChar(max)) as StoredProcedure FROM Master.dbo.syscacheobjects C JOIN Master.dbo.sysdatabases D ON C.dbid = C.dbid WHERE D.Name = DB_Name() -- AND ObjType = 'Adhoc' ORDER BY StoredProcedure 查找出缓存命中率高的存储过程 关键字: syscacheobjects
  14. 14. 服务器整体数据库 IO 压力分析 <ul><li>WITH DBIO AS </li></ul><ul><li>( </li></ul><ul><li>SELECT </li></ul><ul><li>DB_NAME(IVFS.database_id) AS db, </li></ul><ul><li>CASE WHEN MF.type = 1 THEN 'log' ELSE 'data' END AS file_type, </li></ul><ul><li>SUM(IVFS.num_of_bytes_read + IVFS.num_of_bytes_written) AS io, </li></ul><ul><li>SUM(IVFS.io_stall) AS io_stall </li></ul><ul><li>FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS IVFS </li></ul><ul><li>JOIN sys.master_files AS MF </li></ul><ul><li>ON IVFS.database_id = MF.database_id </li></ul><ul><li>AND IVFS.file_id = MF.file_id </li></ul><ul><li>GROUP BY DB_NAME(IVFS.database_id), MF.type </li></ul><ul><li>) </li></ul><ul><li>SELECT db, file_type, </li></ul><ul><li>CAST(1. * io / (1024 * 1024) AS DECIMAL(12, 2)) AS io_mb, </li></ul><ul><li>CAST(io_stall / 1000. AS DECIMAL(12, 2)) AS io_stall_s, </li></ul><ul><li>CAST(100. * io_stall / SUM(io_stall) OVER() </li></ul><ul><li>AS DECIMAL(10, 2)) AS io_stall_per, </li></ul><ul><li>ROW_NUMBER() OVER(ORDER BY io_stall DESC) AS rn </li></ul><ul><li>FROM DBIO </li></ul><ul><li>ORDER BY io_stall DESC; </li></ul>关键字: sys.dm_io_virtual_file_stats
  15. 15. 索引利用率分析 <ul><li>select b.name,a.* from sys.dm_db_index_usage_stats a inner join sysindexes b </li></ul><ul><li>on (a.object_id = b.id) order by a.user_seeks desc </li></ul><ul><li>结合表设计和索引,以及表的功能来综合分析索引环境是否合适。 </li></ul>关键字: sys.dm_db_index_usage_stats
  16. 16. CPU 耗时分析 <ul><li>SELECT </li></ul><ul><li>total_cpu_time, </li></ul><ul><li>total_execution_count, </li></ul><ul><li>total_cpu_time/total_execution_count as cpu_time_per_execution, </li></ul><ul><li>number_of_statements, </li></ul><ul><li>s2.text </li></ul><ul><li>--(SELECT SUBSTRING(s2.text, statement_start_offset / 2, ((CASE WHEN statement_end_offset = -1 THEN (LEN(CONVERT(NVARCHAR(MAX), s2.text)) * 2) ELSE statement_end_offset END) - statement_start_offset) / 2) ) AS query_text </li></ul><ul><li>FROM </li></ul><ul><li>(SELECT TOP 50 </li></ul><ul><li>SUM(qs.total_worker_time) AS total_cpu_time, </li></ul><ul><li>SUM(qs.execution_count) AS total_execution_count, </li></ul><ul><li>COUNT(*) AS number_of_statements, </li></ul><ul><li>qs.sql_handle --, </li></ul><ul><li>--MIN(statement_start_offset) AS statement_start_offset, </li></ul><ul><li>--MAX(statement_end_offset) AS statement_end_offset </li></ul><ul><li>FROM </li></ul><ul><li>sys.dm_exec_query_stats AS qs </li></ul><ul><li>GROUP BY qs.sql_handle </li></ul><ul><li>ORDER BY SUM(qs.total_worker_time)/SUM(qs.execution_count) DESC) AS stats </li></ul><ul><li>CROSS APPLY sys.dm_exec_sql_text(stats.sql_handle) AS s2 </li></ul>在数据库 CPU 居高不下的情况下直接对症查找为什么 CPU 会很高。 关键字: sys.dm_exec_query_stats
  17. 17. 总体分析执行计划 <ul><li>CREATE PROCEDURE LookForPhysicalOps (@op VARCHAR(30)) </li></ul><ul><li>AS </li></ul><ul><li>SELECT sql.text, qs.EXECUTION_COUNT, qs.*, p.* </li></ul><ul><li>FROM sys.dm_exec_query_stats AS qs </li></ul><ul><li>CROSS APPLY sys.dm_exec_sql_text(sql_handle) sql </li></ul><ul><li>CROSS APPLY sys.dm_exec_query_plan(plan_handle) p </li></ul><ul><li>WHERE query_plan.exist(' </li></ul><ul><li>declare default element namespace &quot;http://schemas.microsoft.com/sqlserver/2004/07/showplan&quot;; </li></ul><ul><li>/ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = sql:variable(&quot;@op&quot;)] </li></ul><ul><li>') = 1 </li></ul><ul><li>GO </li></ul><ul><li>EXEC LookForPhysicalOps 'Clustered Index Scan' </li></ul><ul><li>EXEC LookForPhysicalOps 'Nested Loops' </li></ul><ul><li>EXEC LookForPhysicalOps 'Table Scan' </li></ul>关键字: sys.dm_exec_query_stats
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×