数据库基础笔记分享,深入探讨SQL

2019-10-14 17:24 来源:未知

DAC(Dedicated Admin Connection)是SQL Server 2005引入的一个东西,目的是在SQL Server发生严重性能问题的时候仍保留有限的资源保证管理员能够执行一些简单的命令用于问题诊断、释放资源、杀死肇事进程等。微软官方对DAC的说明:使用专用管理员连接.aspx)。对于DAC使用的一般情况,有两个不错的Blog值得推荐:

一.概述

前言

上面的两篇blog涉及到的基本是DAC访问单机单实例的情况。本文试图对DAC访问单机多实例的情况也做个探讨。

   CXPACKET是指:线程正在等待彼此完成并行处理。什么意思呢? 当sql server发现一条指令复杂时,会决定用多个线程并行来执行,由于某些并行线程已完成工作,在等待其它并行线程来同步,这种等待就叫CXPACKET。

本文是个人学习SQL Server 数据库时的以往笔记的整理,内容主要是对数据库的基本增删改查的SQL语句操作约束,视图,存储过程,触发器的基本了解。

1)单机单SQL Server实例,且SQL Server实例使用默认端口(1433)

  为什么会有并行线程呢?  因为在sql server 里有个任务调度SCHEDULER是跟操作系统CPU个数 默认是一 一匹配的,  我们也可能通过sp_configure来设置最大并行度,也就是Max Degree of Parallelism (MAXDOP)。 关于调度可参考" sql server 任务调度与CPU"

注:内容比较基础,适合入门者对SQL Server 数据库的了解!!!

--以下的形式都可以访问
sqlcmd -S myServer -U myUser -P myPassword -A
sqlcmd -S ADMIN:myServer -U myUser -P myPassword
sqlcmd -S myServer,1434 -U myUser -P myPassword
sqlcmd -S xxx.xxx.xxx.xxx -U myUser -P myPassword -A
sqlcmd -S xxx.xxx.xxx.xxx,1434 -U myUser -P myPassword

说明:
a) sqlcmd命令行中参数与参数值之间可以有空格也可以没有;如果你的密码中有空格,你可以用双引号把你的密码引起来;
b) sqlcmd命令中的“-S”其实也可以用"/S",其它参数也一样;
c) 1434是SQL Server连接的默认端口号;
d) 在服务器前加"ADMIN:"也是为了指定进行DAC连接;
e) “-A”是在sqlcmd命令行中指定DAC连接的参数;
f) "-A","ADMIN:",",1434"不能在一条命令中出现两个或以上,否则会报错;
g) 不在命令行中加入这3个参数("-A","ADMIN:",",1434")的任何一个,登录也能成功,差别在于你使用的连接是普通连接,不是DAC连接。一般来说,普通连接能用的资源更多,但是当系统性能出现严重问题的时候普通连接可能没法建立,这也是引入DAC的初衷;再就是DAC连接下能看到一些有助于诊断的秘密视图(参见上面推荐的第一个blog)。

  并行处理的优势: 用多个线程来执行一个指令,当sql server发现一条指令复杂时或语句中含有大数据量要处理,此时执行计划会决定用多个线程并行来执行,从而提高整体响应时间,例如一个指令读入100w条记录, 如果用一个线程做 可能需要10秒, 如果10个线程来做 可能只需要1秒,加上线程间同步时间也不过2秒。

正文

2)单机单SQL Server实例,SQL Server实例使用非默认端口

  并行处理的劣势:1是并行线程要等待同步。2是由于这10个线程全力以赴,就有10个对应的cpu,这样别的用户发过来的指令就会受到影响,甚至拿不到cpu来执行。所以对于并发度要求高的需要及时响应的,一般会建议手动设置每个指令的并行线程数。反之可以不设置Max Degree of Parallelism由系统默认去并行或者设少一点并行度。

1.子查询

我通过测试得到的结论是:对于单机单SQL Server实例,使用非默认端口时候的DAC访问跟使用默认端口1433时候完全一样。网上的一些论坛说要确保“SQL Server Browser”在运行,似乎不是必要的,至少我测试(用的SQL Server 2008 R2 SP3)过程中“SQL Server Browser”是不是在运行不影响访问。

   1.1   查询 CXPACKET的等待

--把一个查询结果作为另外一个查询的查询源
select * from (select * from Student where tbage between 3 and 5)
as ct where tbname=5 --ct是新创的表名

3)单机多SQL Server实例

  借助上一次性能调优的资源等待统计图,会发现等待时间最长的就是CXPACKET类型。

--把另外一个查询的结果作为当前查询的条件来使用。
--子查询中=、!= 、< 、> 、<= 、>=之后只能返回单个值,如果多个值就会报错
--解决办法 可以用in 代替
select * from Student
where tbage in(select tbage from Student where tbname=3)

通过DAC来访问单机多SQL Server实例的情况要复杂一些。上面的几条命令行在这种情况下都会失效。原因在两个:
a) DAC访问是实例级别的,服务端得有办法知道你要访问的是哪个实例;
b) 在单机多实例的情况下监视DAC访问的是随机端口,而不再是默认的1434(当然,具体的端口号在SQL Server启动的时候是确定的,可以在SQL Server启动的Log中找到:打开SSMS--->连接到数据库实例--->Management--->SQL Server Logs--->Current,在里面找到类似”Dedicated admin connection support was established for listening locally on port 50458.“)

--怎么破?
我们在访问数据库引擎的时候,碰到单机多实例的情况有两种办法,一种是在配置S参数的时候加上实例名,一种是加实例端口号。命令行的形式类似下面:
sqlcmd -S myServerInstanceName -U myUser -P myPassword
sqlcmd -S xxx.xxx.xxx.xxxInstanceName -U myUser -P myPassword
sqlcmd -S myServer,6xxx -U myUser -P myPassword
sqlcmd -S xxx.xxx.xxx.xxx,6xxx -U myUser -P myPassword

先从实例名着手:
sqlcmd -S myServerInstanceName -U myUser -P myPassword -A
sqlcmd -S xxx.xxx.xxx.xxxInstanceName -U myUser -P myPassword -A
sqlcmd -S ADMIN:myServerInstanceName -U myUser -P myPassword
sqlcmd -S ADMIN:xxx.xxx.xxx.xxxInstanceName -U myUser -P myPassword

经测试确认,以上4种连接方式都是OK的。注意一点,对于InstanceName的解析是服务器上的“SQL Server Browser”进行的,如果这个服务不在运行,DAC的访问是要失败的。流程是:Browser根据“myServerInstanceName”或者“xxx.xxx.xxx.xxxInstanceName”找到你要访问的实例,然后根据“-A”或者“ADMIN:”找到你要访问的端口。

既然这样可以进行DAC访问,那用类似访问数据库引擎的方式,把上面命令中的“InstanceName”改成",xxxx"格式的端口号是不是也行呢?
sqlcmd -S myServer,xxxx -U myUser -P myPassword -A
sqlcmd -S xxx.xxx.xxx.xxx,xxxx -U myUser -P myPassword -A
sqlcmd -S ADMIN:myServer,xxxx -U myUser -P myPassword
sqlcmd -S ADMIN:xxx.xxx.xxx.xxx,xxxx -U myUser -P myPassword

如果你在几个命令行中配的端口号跟访问数据库引擎时候配置的端口号是一样的话,答案是不行。原因在哪里呢?那个端口是数据库引擎的访问端口,并不是被监听的DAC端口,因为不在一个频道上DAC还不知道你想访问。我的理解,在命令行中指定了端口号的情况下,Browser认为那就是你想访问的端口,结果因为它并不是那个随机的DAC端口而导致了失败。

DAC访问侦听跟数据库引擎一样,从根本上来说也是一个tcp服务(关于这一点你可以查看sys.endpoints来确认)。是服务,我们如果能知道它侦听的端口号就应该能解决问题。但不幸也在这儿,如上面b)所说,在单机多实例的情况下这个被监听的端口是随机的。视图sys.endpoints是能查到当前SQL Server实例上的tcp服务信息的,每个endpoint都有一条记录,比如你就能在这里查到用于镜像的5022,但遗憾的是对于DAC,端口那一列却显示的是0.通过端口访问的这条路我没能走通。

  图片 1

select * from Student
where tbage=(select tbage from Student where tbname=3)

4)DAC访问与防火墙

 1.2  模拟CXPACKET的并行处理 

》》》》》》子查询分页《《《《《《

如果有人通过我上面提到的有效的方式进行DAC访问却不幸失败了,也请不要奇怪。抛开端口劫持等特殊情况,DAC访问失败最常见的就是受到防火墙设置的拦截。对于上面提到的两种单机单实例的情况,只要确认服务端配置了允许对tcp1434端口的访问,DAC连接应该是没有问题的;复杂的情况仍然是单机多实例。

对于单机多实例的情况,由于DAC侦听的端口是随机的,不能指定,所以我们没法在防火墙上给它开口子,除非关闭防火墙。事实上,我在测试的时候就是让服务器上的Windows防火墙对域范围内的访问不起作用(关闭针对域内部访问的拦截)的。那要想从外网访问怎么办?总不能为了一个DAC连接把这台服务器赤裸裸的暴露出来(给它配外网IP)或者关掉公司的级别的防火墙吧?这倒不必,可以用VPN或者端口映射从防火墙上开个小口子,这样你就能连接到局域网,从那进行DAC访问。

     下面是一个分组查询,在执行计划中看到,以采用了并行处理

--1》显示第一页的数据
--分页查询的时候首先是将数据排序
select * from Student order by id desc

5)如何确认当前是DAC连接还是普通连接

 图片 2

--2》第一页 显示5条数据
select Top 5 * from Student order by id desc

可以使用下面的SQL:
select s.session_id,
 s.login_time,
 s.login_name,
 s.host_name,
 p.endpoint_id,
 p.protocol_desc,
 p.name
from sys.dm_exec_sessions s
inner join sys.endpoints p on s.endpoint_id = p.endpoint_id

你可以从login_time,login_name,host_name来判断出哪一个是你当前的连接session,如果是DAC连接的话,你能从name列看到“Dedicated Admin Connection”。

  下面是通过sys.dm_os_waiting_tasks 来查看该语句的task任务。

--3》第二页
select top 5 * from Student
where id not in (select top 5 * from Student order by id desc)
order by id desc

图片 3

--4》第三页
select top 5 * from Student
where id not in (select top (2*5) * from Student order by id desc)
order by id desc

 或采用sys.sysprocesses查看结果。下面一个举例中 会话session是SPID 56。 这里我们明显看到,SQL Server使用了5个线程kpid 来执行这个query。

》》》开窗函数分页《《《

    图片 4

--第七页数据 每页5条数据
--over属于开窗函数

 1.3  分析CXPACKET的并行处理

select * from
(
select * ,row_number() over( order by id desc) as paixu from Student
) as tbl
where tbl.paixu between 6*5+1 and 7*5

  由于并行的原因而从出现了Expacket 的等待。是否并行的执行,通过执行计划可以查看到,下面是查询大表中的数据,sql server自动加启了并行执行。

2.连表查询

   图片 5

--查询所有学生的姓名、年龄及所在班级 (班级在另一个表中)
--当多个列在不同的表中时,要跨表查询,所以一般可以使用inner join
--tc ts是对表名起的别名
select
ts.tsname,
ts.tsage,
tc.tclassname
from TblStudent as ts
inner join TblClass as tc on ts.tsclassid=tc.tclassid(只查询两个表中都有的数据)

  图片 6

--》》》full join 是查询所有的数据(没有的为空)

  共调用了32个线程来并行查询

---子查询写法
select
tsname,
tsage,
班级名称=(select tclassname from TblClass where TblClass.tclassid=TblStudent.tsclassid)
from TblStudent

  图片 7图片 8

--查询学生姓名、年龄、班级及成绩(成绩属于第三张表)
select
ts.tsname,
ts.tsage,
tc.tclasssname,
tscore.tenglish,
tscore.tmath
from TblStudent as ts
inner join TblClass as tc on ts.tsclassid=tc.tclassid 
inner join TblScore as tscore on tscore.tsid=ts.tsid

1.4  控制CXPACKET并行度

 

   有时后台执行的sql, 对于并发度要求不高,  不需要及时响应的,一般会建议手动设置每个指令的并行线程数。

--》》》左外联接(左联接)

  图片 9

--查询没有参加考试的学生的姓名与编号
--把左表(left join 关键字左边的表)中的全部记录都显示出来,对于那些在右表中能找到匹配的记录,显示对应匹配数据,对于那些右表中找不到匹配的记录显示为null
select
ts.tsid,
ts.tsname,
TblScore.*
from TblStudent as ts
left outer join TblSore.tsid=ts.tsid   --outer可以不写

    设置可以发现并行度就二个线程。

--》》》右外联接
--表示要将右表(right join 右边的表)中的所有数据都显示,左表中只显示那些匹配的数据。

    图片 10

select
ts.tsid,
ts.tsname,
TblScore.*
from TblStudent as ts
right outer join TblSore.tsid=ts.tsid

1.5  CXPACKET资源等待总结

--右外联与左外联都是先将匹配的数据找到,然后再将那些没有匹配的数据添加进来,(注意:不是一起查询出来的,有先后顺序)

 (1) 通过实例级别查出CXPACKET的等待时间包括总等时间,平均等待时间,最大等待时间。

--》》》练习:查询所有学生(参加和未参加的考试)的学生姓名、年龄、成绩,如果没有参加考试显示缺考,如果小于english或者math 小于60分显示不及格
select
ts.tsname,
ts.tsage,
tscore.tsid,
case
when tscore.tenglish is null then '缺考'
else convert(varchar(10),tscore.tenglish)
end as 英语成绩,
case
when tscore.tmath id null then '缺考'
else convert (varchar(10),tscore.tmath)
end as 数学成绩,
是否报考=
case
when tscore.tscoreid is null then '是'
else '否'
end
from TblStudent as ts
left join TblScore as tscore on ts.tsid=tscore.tsid

 (2) 查看并行的前十条语句 (这种查询不建议使用,因为条件是查找含有并行parallel的执行计划,查询响应很慢)。

3.视图

SELECT TOP 10
        p.* ,
        q.* ,
        qs.* ,
        cp.plan_handle
FROM    sys.dm_exec_cached_plans cp
        CROSS APPLY sys.Dm_exec_query_plan(cp.plan_handle) p
        CROSS APPLY sys.Dm_exec_sql_text(cp.plan_handle) AS q
        JOIN sys.dm_exec_query_stats qs ON qs.plan_handle = cp.plan_handle
WHERE   cp.cacheobjtype = 'Compiled Plan'
        AND p.query_plan.value('declare namespace p="http://schemas.microsoft.com/SQL Server/2004/07/showplan";
max(//p:RelOp/@Parallel)', 'float') > 0
OPTION  ( MAXDOP 1 )

视图本身并不存储数据,只是存储的查询语句,如果把真实表中的数据修改后,则通过视图查询到的结果也变了。

 (3) 找出cpu和i/o耗性能最高的sql语句, 查看执行计划是否有并行处理。

视图的目的是方便查询,所以一般情况下不能对视图进行增删改查

TAG标签:
版权声明:本文由澳门金莎娱乐网站发布于数据库,转载请注明出处:数据库基础笔记分享,深入探讨SQL