商量select in 在postgresql的效力成績。本站提示廣大學習愛好者:(商量select in 在postgresql的效力成績)文章只能為提供參考,不一定能成為您想要的結果。以下是商量select in 在postgresql的效力成績正文
在知乎上看到如許一個成績:
MySQL 查詢 select * from table where id in (幾百或幾千個 id) 若何進步效力?修正
電商網站,一個商品屬性表,幾十萬筆記錄,80M,索引只要主鍵id,做如許的查詢若何進步效力?
select * from table where id in (幾百或幾千個id)
這些id沒啥紀律,疏散的。。。。
看了一下謎底,感到有很多多少不靠譜的,然則口說無憑,所以在我的電腦上寫了幾個查詢測試一下。我用的是Postgresql9.4,但感到mysql應當也差不多,起首創立一個簡略表,只要簡略的3列,在這個成績的上面很多多少人提到了須要看表的年夜小,其實這個成績和表年夜小有關,只和index的年夜小有關,由於是index是樹立在int上的,所以只和記載數量有關。
Table "public.t9" Column | Type | Modifiers --------+----------------+----------- c1 | integer | c2 | character(100) | c3 | character(200) | Indexes: "i1" UNIQUE, btree (c1)insert into t9 values(generate_series(1000,500000,1),repeat('a',90),repeat('b',180));
以後生成一些隨機數,Mac上用jot,Linux上用shuf
for ((i=0;i<100000;i++)) do jot -r 1 1000 600000 >>rand.file done
然後依據rand.file 生成查詢語句:
select * from t9 where c1 in ( 494613, 575087, 363588, 527650, 251670, 343456, 426858, 202886, 254037, ... 1 );
分離生成3個sql文件,in內變量的數量分離是100,1000和10000個,履行這3個sql文件,看看時光
try psql study -f test_100.sql -o /dev/null LOG: duration: 2.879 ms try psql study -f test_1000.sql -o /dev/null LOG: duration: 11.974 ms try psql study -f test_10000.sql -o /dev/null LOG: duration: 355.689 ms
可以看到只要在in內數據到了10,000個的時刻數據時光會有比擬年夜的變更,但也不外是在300多ms內完成。
那假如依照有些答復那樣,先建一個暫時表,然後用in subquery,而且願望這時候候可以兩表join呢?為了簡略我直接用兩表join了
drop table t_tmp; create table t_tmp(id int); insert into t_tmp (id) values (494613), (575087), (363588), (345980),... (1); select t9.* from t9, t_tmp where t9.c1 = t_tmp.id;
時光若何呢?
try psql study -f test_create_10000.sql -o /dev/null LOG: duration: 2.078 ms LOG: duration: 1.233 ms LOG: duration: 224.112 ms LOG: duration: 322.108 ms
除去drop和create的時光,仍然消費了500+的時光,這裡的條件照樣我用的ssd盤,所以寫LOG的時光會快許多。為何會這麼慢呢?用explain看一下,這時候候數據量較年夜,直接走Merge join 了
那1000行數據的效力若何呢?
try psql study -f test_create_1000.sql -o exp.out LOG: duration: 2.476 ms LOG: duration: 0.967 ms LOG: duration: 2.391 ms LOG: duration: 8.780 ms
100行的數據以下:
try psql study -f test_create_100.sql -o /dev/null LOG: duration: 2.020 ms LOG: duration: 1.028 ms LOG: duration: 1.074 ms LOG: duration: 1.912 ms
可以看到在100個值和1000個值的情形下create table的方法不會比直接在in外面寫一切的變量很多多少少,explain看的話是在用NLJ了。但在數據量更年夜(依照原成績,這裡in的數目其實沒法預知)的情形下效力只會更低,再加上額定的表保護本錢和過剩的SQL語句,DBA確定不愛好的,照樣信任數據庫,寧神年夜膽直接用in list來弄定這些成績吧。
以上內容是針對select in 在postgresql的效力成績,願望對年夜家有所贊助!