山东大学 2020级数据库系统 实验七
What’s more
山東大學 2020級數據庫系統 實驗一
山東大學 2020級數據庫系統 實驗二
山東大學 2020級數據庫系統 實驗三
山東大學 2020級數據庫系統 實驗四
山東大學 2020級數據庫系統 實驗五
山東大學 2020級數據庫系統 實驗六
山東大學 2020級數據庫系統 實驗七
山東大學 2020級數據庫系統 實驗八、九
寫在前面
做數據庫實驗一定要靜得下心來,才能發現其中的錯誤然后進行改正。同時,如果發現 SQL 語句總是報錯,“一定是你錯了,只是不知道錯在哪里!”
其次,SQL 語句中較為復雜的點博主都進行了注釋,希望大家一定要看懂思路后自己寫一遍,而不是盲目的 Ctrl+C,Ctrl+V,切記切記!!
實驗七
本實驗所考察的內容主要是關于索引,索引的建立一般有以下需要注意的點:
· 避免在取值朝一個方向增長的字段(例如:日期類型的字段)上,建立索引;對復合索引,避免將這種類型的字段放置在最前面。由于字段的取值總是朝一個方向增長,新記錄總是存放在索引的最后一個葉頁中,從而不斷地引起該葉頁的訪問競爭、新葉頁的分配、中間分支頁的拆分。此外,如果所建索引是聚集索引,表中數據按照索引的排列順序存放,所有的插入操作都集中在最后一個數據頁上進行,從而引起插入“熱點”。
· 對復合索引,按照字段在查詢條件中出現的頻度建立索引。在復合索引中,記錄首先按照第一個字段排序。對于在第一個字段上取值相同的記錄,系統再按照第二個字段的取值排序,以此類推。因此只有復合索引的第一個字段出現在查詢條件中,該索引才可能被使用。因此將應用頻度高的字段,放置在復合索引的前面,會使系統最大可能地使用此索引,發揮索引的作用。
建立索引的格式:create index index_name on table(name);
- 7-1
1. 將pub用戶下表student的3個列sid,name,birthday復制到表test7_01中。
2. 執行如下查詢,觀察運行速度(5秒以上)。
查詢Samefirstname相同姓氏的人數。
select * from
(select sid,name,birthday,
(select count(*) from test7_01 where substr(name,1,1)=substr(t1.name,1,1)) samefirstname
from pub.student_testindex t1)
where samefirstname=7
3. 為test7_01創建一個僅僅一個索引,保證上面SQL耗時在1秒內。
4. 交卷驗證
思路: - 在什么上建立索引往往取決于 where 中的判斷條件。一般判斷條件是什么,就在什么上建立索引;
- 因此本題中在 substr(name, 1, 1) 上建立索引即可;
- 7-2
1. 將pub用戶下表student的3個列sid,name,birthday復制到表test7_02中。
2. 將出生日期全部修改成一天:
Update test7_02 set birthday=to_date(‘19881018’,‘yyyymmdd’) where substr(sid,12,1)=‘0’;
3. 為test7_02創建一個僅僅一個索引,保證下面SQL耗時在1秒內。
Samenamebirthday同名同生日的人數,Samebirthday相同出生日期的人數
select * from
(select sid,name,birthday,
(select count() from test7_02 where name=t1.name and birthday=t1.birthday) samenamebirthday,
(select count() from test7_02 where birthday=t1.birthday) samebirthday
from pub.student_testindex t1)
where samebirthday=403
4. 交卷驗證
5. 思考題,test7_02不增建索引情況下,下面這個查詢能使用索引嗎?改進后能使用索引嗎?
select * from
(select sid,name,birthday,
(select count(*) from test7_02 where name=t1.name) samename
from pub.student t1)
where samename=7
思路: - 根據上面所提到的原則:應用頻度高的字段應放在復合索引的前面;由于我們把生日都設在了同一天,因此 birthday 才是應用頻度最高的字段,應將其放在第一個;(前提條件是 where 中即用了 name 來查詢,也用了 birthday 來查詢)
接下來是根據索引修改條件的題目,基本原則就是:建立了索引的屬性在 where 子句中要保持原樣,運算符號 >, <, = 左邊不能對它進行運算,也不能對它使用函數等操作
- 7-3
1. pub用戶下表student已經用下面兩句SQL創建了兩索引。
Create index student_birthday on student(birthday);
Create index student_name on student(name);
2. 下面SQL不能用索引耗時超過2秒,在邏輯不變情況下,修改SQL中標為記紅色的子查詢的where條件部分,不要修改其它地方,使其能使用索引。
說明:因為pub.student_testindex數據行數太少,不能通過修改主句where繞過問題。
查詢samefirstname同姓氏的人數。
select * from
(select sid,name,birthday,
(select count(*) from pub.student
where substr(name,1,1)=substr(t1.name,1,1)
) samefirstname
from pub.student_testindex t1) where samefirstname=7
3. 修改以后驗證耗時在2秒之內,將修改以后語句創建成視圖create view test7_03 as select ……。
4. 交卷驗證
思路: - 該問需要查詢同姓的學生信息,可以使用模糊查詢 like 來進行,但需要注意怎樣將“姓”和“%”進行連接呢?
- 想到了 rpad(str1, position, str2) 函數,表示在 str1 的右邊第三個字節的位置連接 str2 字符,這樣便可實現該功能;(或者 concat 函數也可以連接字符串)
-
7-4
1. pub用戶下表student已經用下面兩句SQL創建了兩索引。
Create index student_birthday on student(birthday);
Create index student_name on student(name);
2. 下面SQL不能用索引耗時超過1秒,在邏輯不變情況下,修改SQL中標為記紅色的子查詢的where條件部分,不要修改其它地方,使其能使用索引。
說明:因為pub.student_testindex數據行數太少,不能通過修改主句where繞過問題。
select * from
(select sid,name,birthday,
(select count() from pub.student
where to_char(birthday,‘yyyymm’)=to_char(t1.birthday,‘yyyymm’)
) sameyearmonth,
(select count() from pub.student
where extract (year from birthday) =extract (year from t1.birthday)
) sameyear
from pub.student_testindex t1) where sameyearmonth=35
3. 修改以后驗證耗時在1秒之內,將修改以后語句創建成視圖create view test7_04 as select ……。
4. 交卷驗證
函數介紹: - trunc(t1.birthday, ‘mm’) – 獲取當前日期月份的第一天;
- last_day(t1.birthday) – 獲取當前日期月份的最后一天;
- trunc(t1.birthday, ‘yyyy’) – 獲取當前日期年的第一天;
- add_months(date, number) – 在 date 上加 number 個月;
思路:
1. 本問需要求的是同年月以及同年的學生的 sid, name, birthday;
2. 同年月的學生的生日應該在當月的第一天和當月最后一天之間,trunc(t1.birthday, ‘mm’) 得到第一天,last_day(t1.birthday) 得到最后一天,使用 between 連接即可;
3. 同年的學生的生日應該在當年的第一天和當年最后一天之間,trunc(t1.birthday, ‘yyyy’) 得到當年的第一天,add_months(trunc(t1.birthday, ‘yyyy’), 12) 得到后一年的第一天,再 -1 得到當年的最后一天;
- 7-5
1. pub用戶下表student已經用下面兩句SQL創建了兩索引。
Create index student_birthday on student(birthday);
Create index student_name on student(name);
2. 下面SQL不能用索引耗時超過1秒,在邏輯不變情況下,修改SQL中標為記紅色的子查詢的where條件部分,不要修改其它地方,使其能使用索引。
說明:因為pub.student_testindex數據行數太少,不能通過修改主句where繞過問題。
查詢nextbirthday晚一天出生的人數
select * from
(select sid,name,birthday,
(select count(*) from pub.student
where birthday-1=t1.birthday
) nextbirthday
from pub.student_testindex t1) where nextbirthday=7
3. 修改以后驗證耗時在1秒之內,將修改以后語句創建成視圖create view test7_05 as select ……。
4. 交卷驗證
思路: - 由于不能對建立了索引的屬性進行運算等操作,因此直接把 birthday-1 = t1.birthday 改成 birthday = t1.birthday + 1 即可;
再次強調:一定是看懂思路之后自己實踐哈~~
有問題還請斧正!
總結
以上是生活随笔為你收集整理的山东大学 2020级数据库系统 实验七的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python基础入门(10)之循环语句
- 下一篇: 【youcans 的 OpenCV 例程