台灣最大程式設計社群網站
線上人數
1300
 
會員總數:246037
討論主題:189624
歡迎您免費加入會員
討論區列表 >> MS SQL >> 複合索引的先後順序問題
[]  
[我要回覆]
1
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
複合索引的先後順序問題
價值 : 500 QP  點閱數:503 回應數:6
樓主

缺氧的羊:窒息
高級顧問
52736 128
20888 5957
發送站內信

捐贈 VP 給 缺氧的羊:窒息
前言,(我不是DBA, 沒有專門在研究這塊, 但我一直在納悶自己建的索引到底有沒有問題)

依據已知的文獻(網路,書籍), 索引採用 B tree (或B+ tree) 的方式來建立,
因此, 當一個索引定義為 [A, B, C] 的時候,

where條件為 A = xxx
where條件為 A = xxx And B = XXX
where條件為 A = xxx And B = XXX And C = XXX
(以上3種狀態都可以有效利用該索引)

where條件為 B = XXXX (這個狀態無法使用到上述的索引)

==(回正題)======================================

在電子商務網站系統中, 例如 訂單資料表 (有下單時間, 有店家代號, 訂單總金額)
(不考慮明細的狀況下)


如果要用1組 複合索引來同時解決以下問題, 有可能嗎?
1. [今年度], [各店家]的平均營業額
where 下單時間 between 今年, broup by 店家代號

2. [本月]訂單記錄
where 下單時間 本月

3. [單一店家]自行查詢[本月的訂單記錄]
where 店家代號 = XXX and 下單時間 between 本月


.
..
...
....
.....(人老了, 邏輯怪怪的, 連個問題都不知道要怎麼問才好...)

.....我真正想問的是 [ 複合索引的先後順序 ] 的疑問
也就是所謂的
索引A [ 店家代號, 下單時間 ]
索引B [ 下單時間, 店家代號 ]
(店家代號會大量重複, 而下單時間不可能重複)

依照網路查到的資料, where條件重複率愈低的, 似乎要擺愈前面
但如果採用索引B, 下單時間就已經是完全沒有重複, 那店家代號的意義在哪?

(我一直以為是店家代號擺前面, 下單時間擺後面才合適)


以下是其中一部份比較白話文一點點的參考網站
https://kknews.cc/zh-tw/code/xlogxq8.html
https://ithelp.ithome.com.tw/articles/10185768
https://dotblogs.com.tw/ricochen/2015/07/05/151734

======================================================

另一個問題: 針對索引這件事, 有什麼建議的參考書籍嗎?(或是網路電子書?)

搜尋相關Tags的文章: [ 索引 ] , [ index ] ,
本篇文章發表於2020-05-31 22:11
== 簽名檔 ==
[再難的程式,當你知道怎麼寫時,就很簡單,問題就在於不知道怎麼寫]
[當你辛辛苦苦,嘔心瀝血,寫出一支你覺得沒有人寫的出來的程式時,
你會發現,早就已經有人寫出來了,不但寫的更好,而且還提供Source Code]
[Suffocation Sheep]

厚黑學鋸箭法:
鋸箭法是說有人中了箭,請外科醫生治療,
外科醫生把箭幹鋸了,然後就說弄好了,剩下的箭頭請找內科醫生…
1樓
回應

pilipala
檢舉此回應
羊大疑惑,應該要看這篇文章,從選擇性去做抉擇

[SQL SERVER][Performance]密度和選擇性
本篇文章回覆於2020-06-01 23:06
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
2樓
不錯的參考

pilipala
檢舉此回應
書籍部分可以去圖書館找這兩本
SQL Server Performance Tuning 效能調校
SQL Server效能調校

線上課程
SQL Server實戰效能調校第二部曲:資料表和索引設計一點訣
本篇文章回覆於2020-06-02 00:17
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
3樓
最有價值解答

pilipala
檢舉此回應
再補上一個 Techday 2013 - 深入討論Microsoft SQL Server索引使用技巧
本篇文章回覆於2020-06-02 00:21
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
4樓
回應

香帥
檢舉此回應
一般要看用途來決定
商店代號,就像銀行帳號一樣,當客戶進入索引查詢時,會記得自己的帳號。
一般會用它來查所有的交易狀況。
至於倒過來,若以下單時間為主,就像這個月您有與銀行往來存提款進進出出,自己都可能記不住的。
僅能概略的以在某段時間來做索引,因此若以下單時間為先,資料量會很大
就像銀行一樣,該段時間,銀行所有客戶上百萬或千萬,都可能在裡面,而不是直接先找到。
相反的以商店代號為先,就直接縮小範圍,為唯一直接先找到,速度會很快。
且若資料量太大,下單時間若在兩年前,像我們的系統,線上的大約都只有最近兩年,兩年前的資料都要另外寫需求給系統管理人員,不能直接索引。
因此以下單時間為主的索引,若資料量很大,大部份是系統資料庫人員在管理,很難在線上給使用者做索引。
本篇文章回覆於2020-06-03 01:13
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
5樓
作者回應

缺氧的羊:窒息
捐贈 VP 給 缺氧的羊:窒息 檢舉此回應
to pilipala,那個影片真的不錯,講師的實務經驗就是讚
(只可惜影片中雖然還是講到先後先後很重要,但並沒有給出解答,只有一切看環境)

書籍就得找時間去翻翻看了
===============================

to 香帥,
我主要就是針對む訂單め,單就一個每天都有數千筆交易記錄的商城系統來說,
100萬筆資料的訂單記錄(差不多一整年累計),用商店代號來分,20家店來撈的話平均各佔50000筆(如果要統計全年各店家的營業額的話),


每家店,正常每天都會去看自己的當日訂單
所以店家的where條件通常是【訂單為當日,商店代號為自己】

而總公司會看的是む當日め
所以總公司後台的where條件通常是【訂單為當日】


目前我只用了む訂單日期め去設定單一索引,還沒有什麼大問題,
(但就是被複合索引卡著)


===========
現在看起來,北風資料庫還真的是,電子商務最泛用的demo範例

本篇文章回覆於2020-06-03 21:32
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
6樓
不錯的參考

香帥
檢舉此回應
我幫您以十幾年前我買的書SQL Server 2005完全實戰(章立民研究室)來解答這問題,(7-21頁)
[於定義多重鍵值索引時,辯識度高的欄位或是能傳回較低百分比之資料記錄的欄位應該擺在前面]
因此當您只有查詢む當日め(5樓所說),資料遠低於查詢該店代號傳回資料量的話,那日期應該擺在前面。
相反的若您查的日期,是一段很長時間,資料遠大於用該店代號查的資料量的話,那商店代號應該擺在前面。


本篇文章回覆於2020-06-04 22:54
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
   
1

回覆
如要回應,請先登入.