图片 1

SQL语句处理顺序的坑,无法访问SQL

背景:

首先看下面一条比较完成语句,都是比较常见的关键字。

在SQL
Server
2012(11.0.7001.0)下面在还原一个数据库(备份文件40多G大小,实际数据库大小300G),在还原过程中,出现一直等待ASYNC_IO_COMPLETION,如下测试截图所示,已经等待了72分钟了,但是还原比例依然为0%

  朋友的环境第二天突然访问不了SQL Server,远程SQL
Server用户无法登陆,但是本地SQL Server用户登录正常。

USE Temp;

SELECT empid, YEAR(orderdate) AS orderyear, COUNT(*) AS numorders
FROM Sales.Orders
WHERE custid = 71
GROUP BY empid, YEAR(orderdate)
HAVING COUNT(*) > 1
ORDER BY empid, orderyear;

 

报错:

我们来详细分析一下sql语句的逻辑处理顺序,虽然select在每条语句的第一位,但实际上它是被最后才处理的

SELECT  r.session_id ,

        r.command ,

        r.start_time,

        r.status,

        r.wait_type,

        CONVERT(NUMERIC(6, 2), r.percent_complete)   AS [Percent Complete(%)] ,

        CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time,

                                     GETDATE()), 20) AS [ETA Completion Time] ,

        CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [Elapsed Min] ,

        CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETA Min] ,

        CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0

        / 60.0) AS [ETA Hours] ,

        CONVERT(VARCHAR(1000), ( SELECT SUBSTRING(text,

                                                  r.statement_start_offset / 2,

                                                  CASE WHEN r.statement_end_offset = -1

                                                       THEN 1000

                                                       ELSE ( r.statement_end_offset

                                                              - r.statement_start_offset )

                                                            / 2

                                                  END)

                                 FROM   sys.dm_exec_sql_text(sql_handle)

                               )) AS CommandText

FROM    sys.dm_exec_requests r

WHERE   command IN ( 'RESTORE DATABASE', 'BACKUP DATABASE','RESTORE LOG' );

  用户XX登录失败(MicroSoft SQL Server,错误18456)

1.from  

 

排查:

2.where

 

  对与无法连接服务器的,一般的排查手段,也是最常用的手段。

3.group by

 

  1.因为本地登录正常,那么查看1433端口是否监听。

4.having

图片 1

  2.远程 telnet 1433 端口是不是通的。

5.select

 

  经过排查发现,监听正常,telnet 也是通的。

6.order by

当然,这里是实验,如果还要继续等待的话,相信这个时间会更长。这个是比较让人奇怪的现象。后面查了一下这个跟即时文件初始化(Instant
File Initialization
(IFI))有关。关于这个概念,可以参考官方文档数据库文件初始化
,摘抄部分内容如下所示:

  这个时候就开始犯愁了,telnet
通的按理没理由无法连接到远程服务器上。于是我使用SQLCMD登录仔细看看
18456的错误的state 到底是多少,发现State是1。

7.TOP

 

  到这里就无解了,从来没见过这样的情况。

在仔细分析每个执行顺序代表的意思 (它的实际顺序)

 

处理:

FROM Sales.Orders
WHERE custid = 71
GROUP BY empid, YEAR(orderdate)
HAVING COUNT(*) > 1
SELECT empid, YEAR(orderdate) AS orderyear, COUNT(*) AS numorders
ORDER BY empid, orderyear;

 

  重点来了,第二天,我朋友和我说,是因为加了网闸设备导致的。

1.从 Orders 表查询数据

数据库文件初始化

 

2.根据条件筛选客户ID等于71的

 

3.对客户id和订单年度 进行分组

初始化数据和日志文件以覆盖之前删除的文件遗留在磁盘上的任何现有数据。 执行以下其中一项操作时,应首先通过零填充(用零填充)数据和日志文件来初始化这些文件:

  1. 再选出大于一个订单的组

 

5.返回查询出的数据 以及你要展示的字段

·        
创建数据库。

6.最终对客户id 和订单 进行排序

·        
向现有数据库添加数据或日志文件。

7.输出

·        
增大现有文件的大小(包括自动增长操作)。

输入的键入顺序和处理顺序不一致是有原因的,SQL设计师是为了让用户按照英文的方式提供自己的请求

·        
还原数据库或文件组。

建议、坑

 

  1. from 表时  最好给定 库名和表名  Sales.Orders 
    让表显示表示 不用程序检索。

文件初始化会导致这些操作花费更多时间。 但是,首次将数据写入文件后,操作系统就不必用零来填充文件

  1. where 子句相当重要  SQL Server 会对where 条件
    进行评估访问请求数据要使用的索引,通过索引可以大大减少表扫描时间

 

同时 where 子句检索 完成后 
它返回的是检索结果为True的行  ,但始终记住, SQL
数据库使用三值谓词逻辑,也就是说有三个结果。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签:
网站地图xml地图