關於order by中的資料排序
今天開發的一個同事找到我,說碰到一個比較奇怪的問題,有兩個等價的查詢類似下面的形式。
select *from test where account_id=xxxxxx order by creation_date
select *from test where account_id=xxxxxx and entity_id=xxxxx order by creation_date
兩個查詢都會返回4條結果,但是第一個查詢和第二個查詢的結果排序結果不一致。
使用第一個查詢的結果如下:
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
使用第2個查詢的結果如下
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 1 130000000003403
09-AUG-14 170000501 2 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
order by的時候是根據第1個欄位排序的,但是第3個欄位的排序結果卻不同。單純從sql語句的角度來說,似乎也是合乎情理的。
當時首先想到的就是把creation_date格式化為更加精細的日期格式,精確到秒,看看時間,結果檢視了最終的日期格式,發現精度都一樣,印象中10g以後的order by演算法做了變更。是不是這個原因導致的呢。
己做了一個簡要的測試,反覆的比較之後發現order by在指定欄位排序後,其它欄位的排序和以下的幾種場景有關。
和rowid有一定的關係
和索引相關
和null值相關
為了證明,我在反覆嘗試之後,使用了下面的例子。
我們建立一個表test,然後插入一些針對性的資料。
create table test(creation_date date,ACCOUNT_ID number,INST_FROM number,TLG_INST_ID number, CHG_SEQ_NO number);
insert into test values(to_date('2014-09-11','yyyy-mm-dd'),170000501,4,130000000003403,'');
insert into test values(to_date('2014-08-09','yyyy-mm-dd'),170000501,2,130000000003403,'');
insert into test values(to_date('2014-08-09','yyyy-mm-dd'),170000501,1,130000000003403,16310);
insert into test values(to_date('2014-09-0','yyyy-mm-dd'),170000501,3,130000000003403,'');
這個時候查詢結果,可以看到inst_from欄位是按照4,2,1,3的順序顯示的。這個時候沒有任何的排序操作。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403'
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
11-SEP-14 170000501 4 130000000003403
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
我們略做改動,使用order by creation_date,可以看到inst_from欄位會按照2,1,3,4的順序顯示了。這個時候做了排序操作,但是相對前2條資料,因為插入inst_from的順序是按照先2,1的順序來的,所以排序後的結果就是先2,1的順序。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
這個時候我們建立一個索引,注意我們使用了一個含有空值的列 chg_seq_no.
create index inx_test on test(TLG_INST_ID,CHG_SEQ_NO);
create index inx_test on test(TLG_INST_ID);
輸出的排序結果和沒有建立索引沒有什麼區別。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
透過上面的測試,也發現在order by的時候還是存在很多的不確定性,這些都可以透過在order by之後指定排序的列來避免。但是對理解order by來說,這些測試還是能夠看到order by在實現方式上還是有很多的技巧的。
select *from test where account_id=xxxxxx order by creation_date
select *from test where account_id=xxxxxx and entity_id=xxxxx order by creation_date
兩個查詢都會返回4條結果,但是第一個查詢和第二個查詢的結果排序結果不一致。
使用第一個查詢的結果如下:
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 1 130000000003403
09-AUG-14 170000501 2 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
當時首先想到的就是把creation_date格式化為更加精細的日期格式,精確到秒,看看時間,結果檢視了最終的日期格式,發現精度都一樣,印象中10g以後的order by演算法做了變更。是不是這個原因導致的呢。
己做了一個簡要的測試,反覆的比較之後發現order by在指定欄位排序後,其它欄位的排序和以下的幾種場景有關。
和rowid有一定的關係
和索引相關
和null值相關
為了證明,我在反覆嘗試之後,使用了下面的例子。
我們建立一個表test,然後插入一些針對性的資料。
create table test(creation_date date,ACCOUNT_ID number,INST_FROM number,TLG_INST_ID number, CHG_SEQ_NO number);
insert into test values(to_date('2014-09-11','yyyy-mm-dd'),170000501,4,130000000003403,'');
insert into test values(to_date('2014-08-09','yyyy-mm-dd'),170000501,2,130000000003403,'');
insert into test values(to_date('2014-08-09','yyyy-mm-dd'),170000501,1,130000000003403,16310);
insert into test values(to_date('2014-09-0','yyyy-mm-dd'),170000501,3,130000000003403,'');
這個時候查詢結果,可以看到inst_from欄位是按照4,2,1,3的順序顯示的。這個時候沒有任何的排序操作。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403'
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
11-SEP-14 170000501 4 130000000003403
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
我們略做改動,使用order by creation_date,可以看到inst_from欄位會按照2,1,3,4的順序顯示了。這個時候做了排序操作,但是相對前2條資料,因為插入inst_from的順序是按照先2,1的順序來的,所以排序後的結果就是先2,1的順序。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
這個時候我們建立一個索引,注意我們使用了一個含有空值的列 chg_seq_no.
create index inx_test on test(TLG_INST_ID,CHG_SEQ_NO);
這個時候再次使用排序,結果集就有了明顯的差別。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 1 130000000003403 16310
09-AUG-14 170000501 2 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
值得注意的是,如果我們建立的索引不含有空值列,SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 1 130000000003403 16310
09-AUG-14 170000501 2 130000000003403
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
create index inx_test on test(TLG_INST_ID);
輸出的排序結果和沒有建立索引沒有什麼區別。
SQL> select creation_date,ACCOUNT_ID,INST_FROM,TLG_INST_ID, CHG_SEQ_NO from test t where tlg_inst_id='130000000003403' order by creation_date;
CREATION_DATE ACCOUNT_ID INST_FROM TLG_INST_ID CHG_SEQ_NO
------------------ ---------- ---------- ------------------- ----------
09-AUG-14 170000501 2 130000000003403
09-AUG-14 170000501 1 130000000003403 16310
09-SEP-14 170000501 3 130000000003403
11-SEP-14 170000501 4 130000000003403
透過上面的測試,也發現在order by的時候還是存在很多的不確定性,這些都可以透過在order by之後指定排序的列來避免。但是對理解order by來說,這些測試還是能夠看到order by在實現方式上還是有很多的技巧的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1405505/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL:關於排序order by limit值不穩定的說明(1)MySql排序MIT
- MYSQL order by排序與索引關係總結MySql排序索引
- 關於c++11 memory order的理解C++
- MySQL 5.7 ORDER BY排序的優化MySql排序優化
- MySQL Order BY 排序過程MySql排序
- order by改分組排序排序
- 關於oracle中的sql資料型別OracleSQL資料型別
- R排序sort、order、rank、arrange排序
- 關於資料庫中的一些name資料庫
- EJBQL中關於日期型資料的比較
- MySQL distinct 和 order by 排序混淆的替代方案MySql排序
- 關於SQL Server 中的25種資料型別SQLServer資料型別
- MySQL order by 排序結果不正確MySql排序
- 【SQL 學習】排序問題之order by與索引排序SQL排序索引
- 關於 ABAP 的執行時錯誤 ITAB_ILLEGAL_ORDER
- thinkphp where in order 按照順序in的迴圈排序PHP排序
- MySQL按指定順序排序(order by field的使用)MySql排序
- 如何理解樹狀sql中ORDER SIBLINGS BY排序的含義SQL排序
- 關於Oracle中重啟資料庫的一個bugOracle資料庫
- oracle中於資料庫相關的常用命令????Oracle資料庫
- 關於java中實現在oracle資料庫中實現對中文首字母進行排序的解決方案JavaOracle資料庫排序
- Oacle中如果按照漢字來排序(order by), 是什麼規則 ?排序
- 關於海量資料常用的資料結構資料結構
- 關於資料湖、資料倉儲的想法
- 網上關於碰撞的資料
- 關於資料共享的問題
- 關於資料備份的概述
- 關於資料的管理和挖掘
- oracle文件中關於group by語句不保證排序正確的描述Oracle排序
- 關於非同步爬蟲排序的困惑非同步爬蟲排序
- 關於mysql5.6 的排序問題.MySql排序
- 關於PHP往mysql資料庫中批次插入資料例項教程PHPMySql資料庫
- 關於大資料和資料庫的討論大資料資料庫
- 3.3.1 關於關閉資料庫資料庫
- ORDER對查詢結果進行排序排序
- MySQL利用索引優化ORDER BY排序語句MySql索引優化排序
- MySql Order By 多個欄位 排序規則MySql排序
- mysql按照漢字拼音進行order by排序MySql排序