PostgreSQLNULL值相對位置與QUERY優化-nullsfirstlast,ascdesc
標籤
PostgreSQL , NULLS FIRST , NULLS LAST , ASC , DESC , 預設行為 , sort
背景
在資料庫中NULL值是指UNKNOWN的值,不儲存任何值,在排序時,它排在有值的行前面還是後面通過語法來指定。
例如
-- 表示null排在有值行的前面
select * from tbl order by id nulls first;
-- 表示null排在有值行的後面
select * from tbl order by id nulls last;
同時對於有值行,可以指定順序排還是倒序排。
-- 表示按ID列順序排
select * from tbl order by id [asc];
-- 表示按ID列倒序排
select * from tbl order by id desc;
預設的排序規則如下:
desc nulls first : null large small
asc nulls last : small large null
當nulls [first|last]與asc|desc組合起來用時,是這樣的。
值的順序如下:
1、DEFAULT:(認為NULL比任意值都大)
desc nulls first : 順序:null large small
asc nulls last : 順序:small large null
2、NON DEFAULT: (認為NULL比任意值都小)
desc nulls last : 順序:large small null
asc nulls first : 順序:null small large
由於索引是固定的,當輸入排序條件時,如果排序條件與索引的排序規則不匹配時,會導致無法使用索引的實惠(順序掃描)。導致一些不必要的麻煩。
索引定義與掃描定義不一致引發的問題
1、建表,輸入測試資料
create table cc(id int not null);
insert into cc select generate_series(1,1000000);
2、建立索引(使用非預設配置,null比任意值小)
create index idx_cc on cc (id asc nulls first);
或
create index idx_cc on cc (id desc nulls last);
3、查詢,與索引定義的順序(指NULL的相對位置)不一致時,即使使用索引,也需要重新SORT。
select * from table order by id desc nulls first limit 1;
select * from table order by id [asc] nulls last limit 1;
用到了額外的SORT
postgres=# explain (analyze,verbose,timing,costs,buffers) select * from cc order by id limit 1;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=27969.43..27969.43 rows=1 width=4) (actual time=263.972..263.972 rows=1 loops=1)
Output: id
Buffers: shared hit=7160
-> Sort (cost=27969.43..30469.43 rows=1000000 width=4) (actual time=263.970..263.970 rows=1 loops=1)
Output: id
Sort Key: cc.id
Sort Method: top-N heapsort Memory: 25kB
Buffers: shared hit=7160
-> Bitmap Heap Scan on public.cc (cost=8544.42..22969.42 rows=1000000 width=4) (actual time=29.927..148.733 rows=1000000 loops=1)
Output: id
Heap Blocks: exact=4425
Buffers: shared hit=7160
-> Bitmap Index Scan on idx_cc (cost=0.00..8294.42 rows=1000000 width=0) (actual time=29.380..29.380 rows=1000000 loops=1)
Buffers: shared hit=2735
Planning time: 0.098 ms
Execution time: 264.009 ms
(16 rows)
3、查詢,與索引定義一致(指NULL的相對位置)時,索引有效,不需要額外SORT。
select * from table order by id desc nulls last limit 1;
select * from table order by id [asc] nulls first limit 1;
不需要額外SORT
postgres=# explain (analyze,verbose,timing,costs,buffers) select * from cc order by id nulls first limit 1;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.42..0.45 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1)
Output: id
Buffers: shared hit=4
-> Index Only Scan using idx_cc on public.cc (cost=0.42..22719.62 rows=1000000 width=4) (actual time=0.013..0.013 rows=1 loops=1)
Output: id
Heap Fetches: 1
Buffers: shared hit=4
Planning time: 0.026 ms
Execution time: 0.022 ms
(9 rows)
小結
在PostgreSQL中順序、倒序索引是通用的。不同的是null的相對位置。
因此在建立索引時,務必與業務的需求對齊,使用一致的NULL相對順序(nulls first 或 nulls last 與asc,desc的搭配)(即NULL挨著large value還是small value),而至於值的asc, desc實際上是無所謂的。
如果業務需求的順序與索引的順序不一致(指null的相對順序),那麼會導致索引需要全掃,重新SORT的問題。
核心改進
1、當約束設定了not null時,應該可以不care null的相對位置,因為都沒有NULL值了,優化器應該可以不管NULL的相對位置是否與業務請求的SQL的一致性,都選擇非Sort模式掃描。
2、改進索引掃描方法,支援環形掃描。
相關文章
- WPF 元素相對另外一個元素的 相對位置
- Hawkeye:TopN慢query的獲取與優化優化
- 軟體教練說:效能優化與效能設計,“相親相愛”的一對優化
- 資料庫效能優化-索引與sql相關優化資料庫優化索引SQL
- 關於CSS中的定位使用子絕父相(子類絕對位置和父類相對位置)CSS
- Js獲取元素相對適口位置JS
- Parallel Query Tuning(並行化查詢優化)Parallel並行優化
- 49_初識搜尋引擎_filter與query深入對比解密:相關度,效能Filter解密
- sql優化相關SQL優化
- [WPF]獲取控制元件間的相對位置控制元件
- 程式碼設定RelativeLayout相對位置設定
- [ Skill ] load 函式優化,識別相對路徑函式優化
- TiDB與MySQL優化器對照TiDBMySql優化
- ios效能優化相關iOS優化
- 系統優化相關優化
- (資料科學學習手札92)利用query()與eval()優化pandas程式碼資料科學優化
- JQuery 獲得絕對,相對位置的座標方法--非常重要jQuery
- js獲取div相對螢幕的座標位置JS
- Oracle優化器:星型轉換(Star Query Transformation )Oracle優化ORM
- laravel-query-builder 對於欄位 值為 null的排序方式LaravelUINull排序
- iOS開發:相對路徑與相對工程名iOS
- 快排的優化(非遞迴 (感覺沒變化遞迴和非遞迴)+ 三個隨機數選取準標準值(和相對的最後的位置交換) + 分割區間法)優化遞迴隨機
- MRAM與其他記憶體技術相比具有相對優勢記憶體
- 數值最優化—優化問題的解(二)優化
- 記憶體優化相關記憶體優化
- Hive優化相關設定Hive優化
- HINT篇---優化器相關優化
- 美人相機啟動優化優化
- 【NULLS】Oracle對SQL排序後NULL值位置的“特殊關照”NullOracleSQL排序
- MySQL索引的最左字首原理與查詢的相關優化MySql索引優化
- 元素的相對定位與絕對定位
- 相對於其他技術而言,雲端計算有哪些相對的優勢?
- jaas相對Filter的優勢在哪裡Filter
- 效能優化的相關策略整理優化
- 淺析Oracle 11g中對資料列預設值變化的優化Oracle優化
- Apache網頁優化與安全優化Apache網頁優化
- HTML絕對路徑與相對路徑HTML
- CSS中的絕對定位與相對定位CSS