SQL 大資料量的優化例子討論

2022-03-31 22:48:27 字數 2530 閱讀 2574

今天在itput上看了一篇文章,是討論乙個語句的優化:

優化的語句:

請問以下語句如何優化:

create

table

aa_001

(    ip 

varchar2(28

), name 

varchar2(10

), password 

varchar2(30

)           )

select

*from

aa_001 

where

ip in(1

,2,3

) order

byname 

desc;--

目前表中記錄有一千多萬條左右,而且in中的值個數是不確定的。

以上就是優化的需要優化的語句和情況。

不少人在後面跟帖:有的說沒辦法優化,有的說將in該為exists,有的說在ip上建立索引復合索引(ip,name)等等。

那這樣的情況,能優化嗎,如何優化?今天就來討論這個問題。

1,資料量1千萬多條。

2,in中的值個數是不確定

3.1 分析資料分布

這裡作者沒有提到ip列的資料的分布情況,目前ip列的資料分布可能有以下幾種:

1,ip列(資料唯一,或者資料重複的概率很小)

2,ip列 (資料不均勻,可能有些資料重複多,有些重複少)

3,ip列 (資料分布比較均勻,資料大量重複,主要就是一些同樣的資料(可能只有上萬級別不同的ip資料等)

解決問題:

1,對於第一種資料分布情況,只要在ip列建立乙個索引即可。這時不管表有多少行, in個數是不確定的情況下,都很快。

2,對應第二中資料分布情況,在ip列建立索引,效果不好。因為資料分布不均勻,可能有些快,有些慢

3,對應第三種資料分布情況,在ip列建立索引,速度肯定慢。

注意:這裡的 order by name desc 是在取出資料後再排序的。而不是取資料前排序 

對於2,3兩個情況,因為都是可能需要取出大量的資料,優化器就採用表掃瞄(table scan),而不是索引查詢(index seek) ,速度很慢,因為這時表掃瞄效率要優於索引查詢,特別是高併發情況下,效率很低。

那對應2,3中情況,如何處理。是將in改成exists。其實在sql server 2005和oracle裡的優化器在in後面資料少時,效率是一樣的。這時採用一般的索引效率很低。這時如果在ip列上建立聚集索引,效率會比較高。我們在sql server 2005中做個測試。

表:[dbo].[[zping.com]]]中有約200萬條資料。包含列userid, id, ruleid等列。按照上面的情況查詢一下類似語句:

select

*from

[dbo].

[[zping.com

]]] 

where

userid in(

'402881410ca47925010cb329c7670ffb',

'402881ba0d5dc94e010d5dced05a0008',

'4028814111a735e90111a77fa8e30384') 

order

byruleid 

desc

我們先看userid的資料分布情況,執行下面語句:

select

userid,

count(*

) from

[dbo].

[[zping.com

]]] 

group

byuserid 

orderby2

這時我們看看資料分布:總共有379條資料,資料兩從1到15萬都有,資料分布傾斜嚴重。下圖是其中一部分。

這時如果在ip上建立非聚集索引,效率很低,而且就是強行索引掃瞄,效率也很低,會發現io

次數比表掃瞄還高。這時只能在ip上建立聚集索引。這時看看結果。

這時發現,搜尋採用了(clustered index seek)聚集搜尋掃瞄。

在看看查詢返回的結果: 

(156603

行受影響)表 '

[zping.com]

'。掃瞄計數 

8,邏輯讀取 

5877

次,物理讀取 

0次,預讀 

0次,lob 邏輯讀取 

0次,lob 物理讀取 

0次,lob 預讀 0次。

表 'worktable

'。掃瞄計數 

0,邏輯讀取 

0次,物理讀取 

0次,預讀 

0次,lob 邏輯讀取 

0次,lob 物理讀取 

0次,lob 預讀 0次。

返回15萬行,才不到6千次io。效率較高,因為這15萬行要排序,查詢成本裡排序佔了51%。當然可以建立(userid,ruleid)復合聚集索引,提高效能,但這樣做dml維護成本較高。建議不採用。

從上面的測試例子可以看出, 優化的解決辦法:

資料分布為1:建立ip索引即可

資料分布為2,3:在ip列建立聚集索引。

SQL大資料量分頁效能優化

目前在進行web api唯讀介面的改造,在改造過程中,發現改在後響應時間和之前區別不是很大,通過測試結果顯示在sql的分頁功能處找到原因,並對其進行優化,優化方案如下。測試內容 此次執行時間對比採用平台資金記錄最多的使用者 user id 36062 測試次數未5次 為避免索引快取每次測試前更改 l...

大資料量分頁優化

用limit offset 時並不是先跳過再查詢 而是 先查詢,再跳過 limit 100w,10 先把100w取出來,然後跳過前100w行,所以大資料分頁用limit很慢 select id,name from lx com 5000000,10 先查詢出來5000000 select id,na...

MySQL大資料量分頁SQL語句優化

分頁程式原理很簡單,這裡就不多說了,本篇文章主要說的是在資料表記錄量比較大的情況下,如何將分頁sql做到更優化,讓mysql執行的更快的方法。一般的情況下,我們的分頁sql語句是這樣的 檢視 列印 1select fromtableorderbyid limit 1000,10 以上sql語句在原理...