当前位置:文档之家› SQL数据库查询优化

SQL数据库查询优化

SQL数据库查询优化
SQL数据库查询优化

一、实验目的

1.熟悉查询查询处理的过程;

2.掌握查询优化的概念,理解查询优化的必要性;

3.了解数据库的查询计划;

4.掌握查询代价的分析方法,并且能通过配置参数或者修改SQL语句来降低

查询代价。

二、实验环境

SQL Server

三、实验学时

2学时

四、实验要求

1)求选修了00002号课程的学生姓名。用SQL表达:

SELECT Student.Sname

FROM Student,SC

WHERE Student.Sno=SC.Sno AND https://www.doczj.com/doc/53797088.html,o=‘00002’

2)三种实现方法:

Q1=πSname(σStudent.Sno=SC.Sno∧https://www.doczj.com/doc/53797088.html,o='2' (Student×SC))

Q2=πSname(σhttps://www.doczj.com/doc/53797088.html,o='2' (Student SC))

Q3=πSname(Student σhttps://www.doczj.com/doc/53797088.html,o='2'(SC))

3)要求:本实验旨在说明查询优化的必要性,只要求把法一Q1与法二Q2和法三 Q3比较,从而说明查询优化的重要性

五、实验内容及步骤

(一)实验数据的准备

-- 1.创建数据库

create database stu_optimization

ON

( NAME = stu_opti,

FILENAME = 'E:\stu_opti\stu_opti.mdf',

SIZE = 100,

MAXSIZE = 500,

FILEGROWTH = 10 )

LOG ON

( NAME = 'stu_opti_log',

FILENAME = 'E:\stu_opti\stu_opti_log.ldf',

SIZE = 50MB,

MAXSIZE = 250MB,

FILEGROWTH = 5MB )

GO

-- 2. 创建学生表

create table s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

go

drop table s

go

-- 3. 为学生表输入数据

--输入30000个计科教育学生

declare @num int

declare @n int

set @num=30000

set @n=1

while @n<=@num

begin

insert into s(sno,sdept)

select '151031'+right('00000'+cast(@n as varchar(5)),5),'计科教育' set @n=@n+1

end

select * from s

--4. 设置学生性别

--(1)设置15000个学生的性别为女性

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 15000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--随机设置个学生的性别为女性

update dbo.s

set ssex='女'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--(2)设置其他学生的性别为男性

update dbo.s

set ssex='男'

where ssex is null

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

select * from s order by sno

--5. 设置学生年龄

--(1)为5000个学生设置其年龄为21岁

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这个学生的年龄为21岁

update dbo.s

set sage=21

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(2)为5000个学生设置其年龄为22岁

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这个学生的年龄为22岁

update dbo.s

set sage=22

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(3)为5000个学生设置其年龄为23岁

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这个学生的年龄为23岁

update dbo.s

set sage=23

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(4)为5000个学生设置其年龄为20岁

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这个学生的年龄为20岁

update dbo.s

set sage=20

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(5)为5000个学生设置其年龄为19岁

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这个学生的年龄为19岁

update dbo.s

set sage=19

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(6)为5000个学生设置其年龄为18岁

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这个学生的年龄为18岁

update dbo.s

set sage=18

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

update s set sage=21 where sage is null select * from s order by sno

--6. 设置学生姓名

--(1)为5000个学生设置其姓名为李

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这些学生的姓名为李

update dbo.s

set sname='李'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(2)为5000个学生设置其姓名为王

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这些学生的姓名为王

update dbo.s

set sname='王'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(3)为5000个学生设置其姓名为王

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这些学生的姓名为陈

update dbo.s

set sname='陈'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(4)为5000个学生设置其姓名为刘

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这些学生的姓名为刘

update dbo.s

set sname='刘'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(5)为5000个学生设置其姓名为张

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中

INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这些学生的姓名为张

update dbo.s

set sname='张'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

--(6)为5000个学生设置其姓名为邱

--创建临时表,其结构与学生表的结构一致

CREATE TABLE #TEMP_s(

sno char(11),

sname char(10),

ssex char(2),

sage tinyint,

sdept char(10))

--从学生表中随机产生行数据插入到临时表中INSERT INTO #TEMP_s

SELECT top 5000 sno,sname,ssex,sage,sdept FROM dbo.s

ORDER BY NEWID()

--设置这些学生的姓名为邱

update dbo.s

set sname='邱'

from dbo.s inner join #TEMP_s

on dbo.s.sno=#TEMP_s.sno

--删除临时表

TRUNCATE TABLE #TEMP_s

DROP TABLE #TEMP_s

-- 7. 创建课程表,录入课程

create table c(

cno char(5),

cname varchar(20),

cpno char(5),

ccredit tinyint)

go

insert into dbo.c(cno,cname,cpno,ccredit)

values

--('00001','计算机导论','',2),

--('00002','高级语言程序设计','',2),

--('00003','离算数学','',3),

--('00004','数据结构','00002',3),

--('00005','c#','00002',2),

--('00006','面向对象程序设计','00005',2),

--('00007','数据库原理','00004',3),

--('00008','操作系统','',3),

--('00009','计算机组成原理','',3),

--('00010','编译原理','',3),

--('00011','软件工程','',2),

--('00012','数字图像处理','',2),

--('00013','https://www.doczj.com/doc/53797088.html,程序设计','',2),

--('00014','平面动画设计','',2),

--('00015','linux操作系统','00008',2),

--('00016','数据库新技术','00007',2),

--('00017','嵌入式技术','',2),

--('00018','算法设计与分析','00004',2),

--('00019','nosql','',2),

('00020','数据库实用技术','00007',2)

select * from c

--8. 创建学生成绩表,录入成绩

--(1)创建学生成绩表sc

create table sc(

sno char(11) not null,

cno char(5) not null,

grade tinyint,

primary key(sno,cno))

go

--(2)录入学号和课程号

declare @sno char(11)

declare s_cursor cursor local for select sno from dbo.s open s_cursor

fetch s_cursor into @sno

declare @s_row int,@n int

set @s_row=30000

set @n=1

while @n<=@s_row

begin

insert dbo.sc(sno,cno)

select @sno, cno from dbo.c

fetch s_cursor into @sno

set @n=@n+1

end

close s_cursor

deallocate s_cursor

--(3)为学生选课表生成成绩

--1)创建学生选课表sc12

create table sc12(

sno char(11),

cno char(5),

grade int,

primary key(sno,cno))

go

--2)将学生选课表sc中的选课信息插入到学生选课表sc12,并随机生成相应的选课成绩declare @sno char(11),@cno char(5)

declare @grdae tinyint

declare sc_cur cursor for select sno,cno from dbo.sc

open sc_cur

fetch next from sc_cur into @sno,@cno

set @grdae=cast( floor(rand()*50) as int)+50

declare @n int,@sc_row int

set @n=1

set @sc_row=600000

while @n<=@sc_row

begin

insert into dbo.sc12(sno,cno,grade)

values(@sno,@cno,@grdae)

fetch next from sc_cur into @sno,@cno

set @grdae=cast( floor(rand()*50) as int)+50

set @n=@n+1

end

close sc_cur

deallocate sc_cur

说明:上面是查询优化数据库的模板程序。由于笛卡尔积计算量非常之大,上面的数据由普通的计算机作为数据服务器难以实现。

(二)实验实现:

本实验在sql server 2000环境下实现

1. 数据库:stu_optimization

1)学生表:s22(5000个元祖)

2)课程表:c22(20个元祖)

3)学生选课表:sc22(100000元祖)

2. 三种方法的时间代价

1)法一Q1中只进行笛卡尔积的时间:

2)法二、法三的时间

这里只是从时间代价上说明查询优化的必要性。通过简单的查询语句难以实现法二和法三在DBMS中的实现细节。

相关主题
文本预览
相关文档 最新文档