上周,技術支持反映:客戶的一個查詢操作需要耗時6.1min左右,在跟進代碼後,簡化了資料庫的查詢後仍然收效甚微。後來,技術總監分析了sql後,給其中的一個表添加的一個非聚集索引(三個欄位)後,同樣的查詢操作耗時只需要6s-7s。 原sql大概需要左聯left join 十幾個 ,left join前 ...
上周,技術支持反映:客戶的一個查詢操作需要耗時6.1min左右,在跟進代碼後,簡化了資料庫的查詢後仍然收效甚微。後來,技術總監分析了sql後,給其中的一個表添加的一個非聚集索引(三個欄位)後,同樣的查詢操作耗時只需要6s-7s。
原sql大概需要左聯left join 十幾個 ,left join前後的兩個表又是笛卡爾積。因此,只要其中有一個表的數據有很多,那麼sql需要檢索的數據集會無比巨大。根據where後面過濾的欄位(至少兩個欄位)添加非聚集索引後,資料庫會自動複製一份數據,然後sql查詢時會去這份複製的數據檢索,這樣就大大地減少了資料庫響應的時間。那麼是否非聚集索引越多越好呢?通常來講,一個表只能有一個聚集索引,但可以有多個非聚集索引。而資料庫索引主要目的就是提高了SQL Server系統的性能,加快數據的查詢速度與減少系統的響應時間 。但這並不意味著索引(非聚集索引)越多越好。恰當的索引設計會顯著提高性能,反之會得不償失。當我們的技術支持給客戶設計索引時,查詢時間仍然沒有如期提高。這就是非聚集索引設計不恰當的例子。因為那三個欄位(前面提到)中包含一個欄位:現場時間,而這個欄位是會動態變化的,客戶查詢操作的一個過濾條件就是時間,所以並沒有如期生效,因為sql查詢時沒有命中這個複製的數據集。所以當減少這個欄位時,查詢時間又回到6s-7s之間,命中率顯著提高。
此外,非聚集索引的增加會增加硬碟(或記憶體)的開銷,世上沒有一舉兩得事情,所以權衡利弊恰當地設計索引尤為重要。