不良的
sql往往來自於不恰當的索引
設計 、不充份的
連 接條件和不可
優 化的
where
子句。 在
對 它們進 行適當的
優 化後,其執行速度有了明
顯 地提高!
下面我將從
這 三個方面分
別進 行
總結 :
一、不合理的索引
設計 ----
例:表record
有 620000
行, 試
看在不同的索引下,下面幾個
sql的運**況:
---- 1.
在 date
上建有一非個群集索引
select count(*) from record where date >'19991201' and date < '19991214'and amount >2000 (25秒)
select date ,sum(amount) from record group by date(55秒)
select count(*) from record where date >'19990901' and place in ('bj','sh') (27秒)
----
分析:----
date
上有大量的重
復值 ,在非群集索引下,資料在物理上隨機存放在資料
頁 上,在範
圍查 找
時 ,必
須執 行一次表
掃 描才能找到
這 一範
圍 內的全部行。
---- 2.
在 date
上的乙個群集索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000 (14
秒)select date,sum(amount) from record group by date(28
秒)select count(*) from record where date >'19990901' and place in ('bj','sh')(14
秒)----
分析:----
在群集索引下,資料在物理上按
順 序在資料
頁 上,重
復值 也排列在一起,因而在範
圍查 找
時 ,可以先找到
這 個範
圍 的起末點,且只在
這 個範
圍 內掃 描資料
頁 ,避免了大範
圍掃 描,提高了
查詢 速度。
---- 3.
在 place
, date
, amount
上的 組
合索引select count(*) from record where date >'19991201' and date < '19991214' and amount >2000 (26
秒)select date,sum(amount) from record group by date(27
秒)select count(*) from record where date >'19990901' and place in ('bj, 'sh')
(< 1
秒)----
分析:----
這 是乙個不很合理的
組 合索引,因
為 它的前
導 列是
place
,第一和第二條
sql沒有引用
place
,因此也沒有利用上索引;第三個
sql使用了
place
,且引用的所有列都包含在
組 合索引中,形成了索引覆蓋,所以它的速度是非常快的。
---- 4.
在 date
, place
, amount
上的 組
合索引select count(*) from record where date >'19991201' and date < '19991214' and amount >2000(< 1秒)
select date,sum(amount) from record group by date(11
秒)select count(*) from record where date >'19990901' and place in ('bj','sh')
(< 1
秒)----
分析:----
這 是乙個合理的
組 合索引。它將
date
作 為前 導
列,使每 個
sql都可以利用索引,並且在第一和第三個
sql中形成了索引覆蓋,因而效能達到了最
優 。---- 5.
總結 :
----
預設情況下建立的索引是非群集索引,但有
時 它並不是最佳的;合理的索引
設計 要建立在
對 各種查詢
的分析和
** 上。
一般來說 : ①
. 有大量重
復值 、且
經 常有範
圍查詢( between, >,<
, >=,< =
)和 order by
、 group by
發 生的列,可考
慮 建立群集索引; ②
. 經常同 時
訪問多列,且
每 列都含有重
復值 可考
慮 建立
組 合索引; ③
. 組合索引要盡量使
關鍵查詢
形成索引覆蓋,其前
導 列一定是使用最
頻 繁的列。
二、不充份的
連 接條件:
例:表card
有 7896
行,在card_no
上有乙個非聚集索引,表
account
有 191122
行,在account_no
上有乙個非聚集索引,
試 看在不同的表
連 接條件下,兩個
sql的 執
**況:
select sum(a.amount) from account a,card b where a.card_no = b.card_no(20
秒)select sum(a.amount) from account a,card b where a.card_no = b.card_no and a.account_no=b.account_no
(< 1
秒)----
分析:----
在第乙個
連 接條件下,最佳
查詢 方案是將
account
作外 層
表, card
作內 層
表,利用
card
上的索引,其
i/o次數可由以下公式估算
為 : 外
層 表account
上的 22541
頁 +(外 層
表 account
的 191122
行 *內 層
表 card
上 對應
外 層表第一行所要
查 找的
3 頁) =595907
次 i/o
在第二個
連 接條件下,最佳
查詢 方案是將
card
作外 層
表, account
作內 層
表,利用
account
上的索引,其
i/o次數可由以下公式估算
為 :外
層 表card
上的 1944
頁 +(外 層
表 card
的 7896
行 *內 層
表 account
上 對應
外 層表 每
一行所要
查 找的
4 頁) = 33528
次 i/o 可
見 ,只有充份的
連 接條件,真正的最佳方案才會被
執 行。 總結
: 1. 多表操作在被
實際執行前,
查詢優化器會根據
連 接條件,列出幾
組 可能的
連 接方案並從中找出系
統開銷最小的最佳方案。
連 接條件要充份考
慮帶 有索引的表、行數多的表;內外表的
選擇 可由公式:外
層 表中的匹配行數
* 內層 表中
每 一次
查 找的次數確定,乘
積 最小
為 最佳方案。 2.
查 看執 行方案的方法
-- 用 set showplan
on ,打
開 showplan
選項 ,就可以看到
連 接順 序、使用何
種 索引的資訊;想看更
詳細 的資訊,需用
sa 角色
執 行dbcc(3604,310,302) 。
漫談資料庫
談到資料庫這個詞,我想無論是菜鳥還是高手都不會感到陌生。隨著資訊化時代的到來,資料庫已被廣泛運用於各類電腦網路和管理系統中。如果沒有資料庫的話,今天的網際網路就不會這樣 絢麗多姿 我們所看到的企業管理系統將只能成為一種電腦的裝飾品。我有不少朋友,雖然他們對資料庫各有自己的看法,但在有一點上是達成共識...
資料庫索引 1
資料庫索引 概念 索引是對資料庫表中一列或者多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。如果想按特定職員的姓名來查詢他或她,則在表中搜尋所有的行進行比較,索引有助於更快的獲取資訊。索引分為聚簇索引和非聚簇索引,聚簇索引是按照資料存放的物理位置為順序的,而非聚簇索引不一樣 聚簇...
資料庫索引雜談1
聚集索引結構 在sql server中,索引是按b 樹結構來進行組織的。聚集索引的資料排列順序與資料的物理排列順 序相同。聚集索引和非聚集索引的根本區別是表記錄的排列順序和與索引的排列順序是否一致.聚集索引表記錄的排列順序與索引的排列順序一致,優點是查詢速度快,因為一旦具有第乙個索引值的紀錄被找到,...