데이터 베이스 MySQL 튜토리얼 MSSQL优化之探索MSSQL执行计划(转)

MSSQL优化之探索MSSQL执行计划(转)

Jun 07, 2016 pm 06:03 PM
mssql 실행 계획

最近总想整理下对MSSQL的一些理解与感悟,却一直没有心思和时间写,晚上无事便写了一篇探索MSSQL执行计划,本文讲执行计划但不仅限于讲执行计划

网上的SQL优化的文章实在是很多,说实在的,我也曾经到处找这样的文章,什么不要使用IN了,什么OR了,什么AND了,很多很多,还有很多人拿出仅几S甚至几MS的时间差的例子来证明着什么(有点可笑),让许多人不知道其是对还是错。而SQL优化又是每个要与数据库打交道的程序员的必修课,所以写了此文,与朋友们共勉。
谈到优化就必然要涉及索引,就像要讲锁必然要说事务一样,所以你需要了解一下索引,仅仅是索引,就能讲半天了,所以索引我就不说了(打很多字是很累的,况且我也知之甚少),可以去参考相关的文章,这个网上资料比较多了。
今天来探索下MSSQL的执行计划,来让大家知道如何查看MSSQL的优化机制,以此来优化SQL查询。
代码如下:
--DROP TABLE T_UserInfo----------------------------------------------------
--建测试表
CREATE TABLE T_UserInfo
(
Userid varchar(20), UserName varchar(20),
RegTime datetime, Tel varchar(20),
)
--插入测试数据
DECLARE @I INT
DECLARE @ENDID INT
SELECT @I = 1
SELECT @ENDID = 100 --在此处更改要插入的数据,重新插入之前要删掉所有数据
WHILE @I BEGIN
INSERT INTO T_UserInfo
SELECT 'ABCDE'+CAST(@I AS VARCHAR(20))+'EF','李'+CAST(@I AS VARCHAR(20)),
GETDATE(),'876543'+CAST(@I AS VARCHAR(20))
SELECT @I = @I + 1
END

--相关SQL语句解释
---------------------------------------------------------------------------
--建聚集索引
CREATE CLUSTERED INDEX INDEX_Userid ON T_UserInfo (Userid)
--建非聚集索引
CREATE NONCLUSTERED INDEX INDEX_Userid ON T_UserInfo (Userid)
--删除索引
DROP INDEX T_UserInfo.INDEX_Userid
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--显示有关由Transact-SQL 语句生成的磁盘活动量的信息
SET STATISTICS IO ON
--关闭有关由Transact-SQL 语句生成的磁盘活动量的信息
SET STATISTICS IO OFF
--显示[返回有关语句执行情况的详细信息,并估计语句对资源的需求]
SET SHOWPLAN_ALL ON
--关闭[返回有关语句执行情况的详细信息,并估计语句对资源的需求]
SET SHOWPLAN_ALL OFF
---------------------------------------------------------------------------
请记住:SET STATISTICS IO 和 SET SHOWPLAN_ALL 是互斥的。
OK,现在开始:
首先,我们插入100条数据
然后我写了一个查询语句:
SELECT * FROM T_UserInfo WHERE USERID='ABCDE6EF'
选中以上语句,按Ctrl+L,如下图
这就是MSSQL的执行计划:表扫描:扫描表中的行
然后我们来看该语句对IO的读写:
执行:SET STATISTICS IO ON
此时再执行该SQL:SELECT * FROM T_UserInfo WHERE USERID='ABCDE6EF'
切换到消失栏显示如下:
表'T_UserInfo'。扫描计数1,逻辑读1 次,物理读0 次,预读0 次。
解释下其意思:
四个值分别为:
执行的扫描次数;
从数据缓存读取的页数;
从磁盘读取的页数;
为进行查询而放入缓存的页数
重要:如果对于一个SQL查询有多种写法,那么这四个值中的逻辑读(logical reads)决定了哪个是最优化的。

接下来我们为其建一个聚集索引
执行CREATE CLUSTERED INDEX INDEX_Userid ON T_UserInfo (Userid)
然后再执行SELECT * FROM T_UserInfo WHERE USERID='ABCDE6EF'
切换到消息栏如下显示:
表'T_UserInfo'。扫描计数1,逻辑读2 次,物理读0 次,预读0 次。
此时逻辑读由原来的1变成2,
说明我们又加了一个索引页,现在我们查询时,逻辑读就是要读两页(1索引页+1数据页),此时的效率还不如不建索引。
此时再选中查询语句,然后再Ctrl+L,如下图:



聚集索引查找:扫描聚集索引中特定范围的行
说明,此时用了索引。
OK,到这里你应该已经知道初步知道MSSQL查询计划和如何查看对IO的读取消耗了吧!


接下来我们继续:

现在我再把测试数据改变成1000条
再执行SET STATISTICS IO ON,再执行
SELECT * FROM T_UserInfo WHERE USERID='ABCDE6EF'
在不加聚集索引的情况下:
表'T_UserInfo'。扫描计数1,逻辑读7 次,物理读0 次,预读0 次。
在加聚集索引的情况下:CREATE CLUSTERED INDEX INDEX_Userid ON T_UserInfo (Userid)
表'T_UserInfo'。扫描计数1,逻辑读2 次,物理读0 次,预读0 次。
(其实也就是说此时是读了一个索引页,一个数据页)
如此,在数据量稍大时,索引的查询优势就显示出来了。



先小总结下:
当你构建SQL语句时,按Ctrl+L就可以看到语句是如何执行,是用索引扫描还是表扫描?
通过SET STATISTICS IO ON 来查看逻辑读,完成同一功能的不同SQL语句,逻辑读
越小查询速度越快(当然不要找那个只有几百条记录的例子来反我)。

我们再继续深入:
OK,现在我们再来看一次,我们换个SQL语句,来看下MSSQL如何来执行的此SQL呢?
现在去掉索引:DROP INDEX T_UserInfo.INDEX_Userid
现在打开[显示语句执行情况的详细信息]:SET SHOWPLAN_ALL ON
然后再执行:SELECT * FROM T_UserInfo WHERE USERID LIKE 'ABCDE8%'
看结果栏:结果中有些具体参数,比如IO的消耗,CPU的消耗。
在这里我们只看StmtText:
SELECT * FROM T_UserInfo WHERE USERID LIKE 'ABCDE8%'
|--Table Scan(OBJECT:([student].[dbo].[T_UserInfo]), WHERE:(like([T_UserInfo].[Userid], 'ABCDE8%', NULL)))
Ctrl+L看下此时的图行执行计划:


我再加上索引:
先关闭:SET SHOWPLAN_ALL OFF
再执行:CREATE CLUSTERED INDEX INDEX_Userid ON T_UserInfo (Userid)
再开启:SET SHOWPLAN_ALL ON
再执行:SELECT * FROM T_UserInfo WHERE USERID LIKE 'ABCDE8%'
查看StmtText:
SELECT * FROM T_UserInfo WHERE USERID LIKE 'ABCDE8%'
|--Clustered Index Seek(OBJECT:([student].[dbo].[T_UserInfo].[INDEX_Userid]), SEEK:([T_UserInfo].[Userid] >= 'ABCDE8' AND [T_UserInfo].[Userid] Ctrl+L看下此时的图行执行计划:

在有索引的情况下,我们再写一个SQL:
SET SHOWPLAN_ALL ON
SELECT * FROM T_UserInfo WHERE LEFT(USERID,4)='ABCDE8%'
查看StmtText:
SELECT * FROM T_UserInfo WHERE LEFT(USERID,4)='ABCDE8%'
|--Clustered Index Scan(OBJECT:([student].[dbo].[T_UserInfo].[INDEX_Userid]), WHERE:(substring([T_UserInfo].[Userid], 1, 4)='ABCDE8%'))
Ctrl+L看下此时的图行执行计划:


我们再分别看一下三种情况下对IO的操作
分别如下:
第一种情况:表'T_UserInfo'。扫描计数1,逻辑读7 次,物理读0 次,预读0 次。
第二种情况:表'T_UserInfo'。扫描计数1,逻辑读3 次,物理读0 次,预读0 次。
第三种情况:表'T_UserInfo'。扫描计数1,逻辑读8 次,物理读0 次,预读0 次。
这说明:
第一次是表扫描,扫了7页,也就是全表扫描
第二次是索引扫描,扫了1页索引,2页数据页
第三次是索引扫描+表扫描,扫了1页索引,7页数据页
[图形界面也有对CPU和IO的消耗,也可以看出来哪个最优!]

通过比较,嘿嘿,很容易的看出:第二种第三种写法在都有索引的情况下,like有效的使用索引,而left则不能,这样一个最简单的优化的例子就出来了,哈哈。

如果以上你都明白了,那么你可能已经对SQL的优化有初步新的想法了,网上一堆堆的SQL优化的文章真的是那样吗?你自己试试就知道了,而不必盲目去记那些东西,自己试试,看看MSSQL到底是怎么来执行就明白了。
在我举的例子中,用的是聚集索引扫描,字段是字母加数字,大家可以试试看纯数字的、字母的、汉字的等等,了解下MMSQL会如何改变SQL语句来利用索引。然后再试试非聚集索引是什么情况?用不用索引和什么有关?子查询MSSQL是如何执行?IN用不用索引,LIKE用不用索引?函数用不用索引?OR、AND、UNION?子查询呢?在这里我不一一去试给大家看了,只要知道了如何去看MSSQL的执行计划(图形和文本),很多事情就很明朗了。

大总结:
实现同一查询功能的SQL写法可能会有多种,如果判断哪种最优化,如果仅仅是从时间上来测,会受很多外界因素的影响,而我们明白了MSSQL如何去执行,通过IO逻辑读、通过查看图示的查询计划、通过其优化后而执行的SQL语句,才是优化SQL的真正途径。

另外提醒下:数据量的多少有时会影响MSSQL对同一种查询写法语句的执行计划,这一点在非聚集索引上特别明显,还有就是在多CPU与单CPU下,在多用户并发情况下,同一写法的查询语句执行计划会有所不同,这个就需要大家有机会去试验了(我也没有这方面的太多经验与大家分享)。

先写这些吧,由于我对MSSQL认识还很浅薄,如有不对的地方,还请指正。
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP를 mssql 데이터베이스에 연결하는 방법 PHP를 mssql 데이터베이스에 연결하는 방법 Oct 23, 2023 pm 12:02 PM

PHP가 mssql 데이터베이스에 연결하는 방법에는 PHP의 MSSQL 확장 사용, PDO 사용 등이 포함됩니다. 자세한 소개: 1. PHP의 MSSQL 확장 방법을 사용하여 PHP에 MSSQL 확장이 설치되어 있는지 확인합니다. mssql 확장이 활성화되어 있는지 여부는 PHP 구성 파일(php.ini)에서 확인할 수 있습니다. 2. PDO 메서드를 사용하여 PHP에 PDO 확장이 설치되어 있는지 확인하세요. PHP 구성 파일(php.ini)에서 pdo_sqlsrv 확장이 활성화되어 있는지 확인할 수 있습니다.

Ubuntu에서 PHP를 설치하고 MSSQL 연결을 구성하는 방법에 대한 자세한 가이드 Ubuntu에서 PHP를 설치하고 MSSQL 연결을 구성하는 방법에 대한 자세한 가이드 Feb 29, 2024 am 11:15 AM

Ubuntu는 서버를 실행하는 데 일반적으로 사용되는 인기 있는 오픈 소스 운영 체제입니다. Ubuntu에 PHP를 설치하고 MSSQL 연결을 구성하는 것은 많은 개발자와 시스템 관리자가 자주 수행해야 하는 작업 중 하나입니다. 이 기사에서는 독자들에게 PHP 설치, Apache 설정, MSSQLServer 설치 등의 단계를 포함한 자세한 가이드를 제공하고 특정 코드 예제를 첨부합니다. 1단계: PHP 및 관련 확장 설치 먼저, PHP 연결을 지원하기 위해 PHP 및 관련 확장을 설치해야 합니다.

Ubuntu 환경에서 MSSQL 데이터베이스를 지원하기 위해 PHP를 설치하는 단계에 대한 자세한 설명 Ubuntu 환경에서 MSSQL 데이터베이스를 지원하기 위해 PHP를 설치하는 단계에 대한 자세한 설명 Feb 29, 2024 am 10:39 AM

Ubuntu 환경에서 MSSQL 데이터베이스를 지원하기 위해 PHP를 설치하는 세부 단계 웹 애플리케이션을 개발할 때 Microsoft SQL Server(MSSQL) 데이터베이스에 연결해야 하는 상황이 자주 발생합니다. Ubuntu 환경에서 PHP를 MSSQL 데이터베이스에 연결하려면 관련 소프트웨어를 설치하고 적절한 설정을 구성해야 합니다. 다음으로 Ubuntu 환경에서 MSSQL 데이터베이스를 지원하기 위해 PHP를 설치하는 단계와 특정 코드를 제공하는 단계를 자세히 소개하겠습니다.

mysql 실행 계획이란 무엇입니까? mysql 실행 계획이란 무엇입니까? Jul 20, 2023 am 10:24 AM

MySQL 실행 계획은 SQL 문을 실행할 때 MySQL 데이터베이스 관리 시스템이 채택한 특정 실행 전략 및 작업 순서를 나타냅니다. 실행 계획은 쿼리 최적화 프로그램에 의해 생성되며 MySQL이 SQL 쿼리를 검색하고 평가하는 프로세스를 설명하며, 개발자가 쿼리 성능을 최적화하는 데 도움이 되도록 인덱스 사용 방법, 조인 작업 수행, 정렬 수행 방법에 대한 중요한 정보를 제공합니다. mysql 실행 계획의 생성 프로세스에는 쿼리 파서, 쿼리 최적화 프로그램 및 실행 프로그램과 같은 구성 요소가 포함됩니다.

Ubuntu에서 PHP 설치 및 MSSQL 데이터베이스 연결에 대한 전체 튜토리얼 Ubuntu에서 PHP 설치 및 MSSQL 데이터베이스 연결에 대한 전체 튜토리얼 Feb 29, 2024 am 11:18 AM

Ubuntu 운영 체제에서 PHP를 설치하고 MSSQL 데이터베이스에 연결하는 것은 많은 개발자와 시스템 관리자가 마스터해야 하는 기술 중 하나입니다. 이 기사에서는 PHP 설치, MSSQL 서버 측 드라이버 설치, MSSQL 데이터베이스에 연결하도록 PHP 구성 및 해당 코드 예제 제공을 포함한 자세한 튜토리얼을 제공합니다. 1부: PHP 설치 먼저 MSSQL 데이터베이스에 연결할 수 있도록 PHP 및 관련 확장을 설치해야 합니다. PHP 및 필요한 확장 기능을 설치하려면 터미널에 다음 명령을 입력하세요.

MySql SQL 문 실행 계획: MySQL 쿼리 프로세스를 최적화하는 방법 MySql SQL 문 실행 계획: MySQL 쿼리 프로세스를 최적화하는 방법 Jun 16, 2023 am 09:15 AM

인터넷의 급속한 발전으로 인해 데이터 저장 및 처리가 점점 더 중요해지고 있습니다. 따라서 관계형 데이터베이스는 현대 소프트웨어 플랫폼의 필수적인 부분입니다. MySQL 데이터베이스는 사용이 간편하고 배포 및 관리가 용이하기 때문에 가장 널리 사용되는 관계형 데이터베이스 중 하나가 되었습니다. 그러나 대용량 데이터를 처리할 때 MySQL 데이터베이스 성능 문제가 문제가 되는 경우가 많습니다. 이번 글에서는 MySQL의 SQL 문 실행 계획을 살펴보고, 쿼리 프로세스를 최적화하여 MySQL 데이터를 개선하는 방법을 소개하겠습니다.

360을 우회하기 위한 mssql 주입 + 화이트리스트 업로드 분석 예시 360을 우회하기 위한 mssql 주입 + 화이트리스트 업로드 분석 예시 May 12, 2023 pm 02:37 PM

정보 수집: 사이트는 vue+aspx+iis8.5를 사용하여 구축되었습니다. 사이트 로그인창에는 버전번호가 있고 URL란에 siteserver라는 단어가 나오므로 cms로 구축한 것으로 의심되는데, cms로 구축한 사이트는 본 적이 없습니다. siteserver cms 버전이 최신이고, 인터넷에서 제공하는 취약점은 로그인창에서 인젝션 + 취약한 비밀번호 + 인증코드 우회 + 무단 기타 방법을 시도해 보았는데 소용이 없었습니다. 계정이 있는 경우 테스트를 위해 사이트에 직접 로그인하기만 하면 됩니다. 사진은 온라인에서 찾은 로그인 사진을 보여줍니다. 빨간색 상자는 cms 프롬프트가 아닌 버전 번호입니다. 기능 테스트: 백그라운드로 진입한 후 주로 페이지 관리에 대한 기능을 간략하게 살펴보았습니다.

우분투에 php mssql 설치하는 방법 우분투에 php mssql 설치하는 방법 Jan 28, 2023 am 09:25 AM

우분투에 php mssql을 설치하는 방법: 1. 터미널 명령 창을 입력합니다. 2. "curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list를 실행합니다. d/ mssql-release.list"; 3. install 명령을 통해 "pdo_sqlsrv"를 설치합니다.

See all articles