2010-01-25 84 views
10

我有一張巨大的桌子可以使用。我想檢查是否有一些parent_id等於我的傳遞值的記錄。 目前我實現這個是通過使用「select count(*)from mytable where parent_id =:id」;如果結果> 0,意味着它們確實存在。因爲這是一個非常大的表格,我不在乎什麼是存在的記錄的確切數量,我只是想知道它是否存在,所以我認爲count(*)有點低效。檢查數據庫表中的某些記錄的最快方法是什麼?

如何以最快的方式實現此要求?我使用的是Oracle 10

根據冬眠提示&技巧https://www.hibernate.org/118.html#A2

這表明,以這樣寫:

整型數=(整數)session.createQuery(「SELECT COUNT(* )from ....「)。uniqueResult();

我不知道uniqueResult()在這裏有什麼魔力?爲什麼它使這個速度更快?

比較「選擇1從mytable where parent_id = passingId和rowrum < 2」,這樣更有效率嗎?

回答

9

一個EXISTS查詢是一個去,如果你不感興趣的記錄數:

select 'Y' from dual where exists (select 1 from mytable where parent_id = :id) 

這將返回「Y」,如果記錄存在並沒有什麼其他方式。

[在上Hibernate的「uniqueResult」你的問題而言 - 這一切都爲返回一個對象時,只有一個對象返回 - 而不是包含1名對象的一組。如果多個結果返回的方法拋出一個異常]

+0

您甚至不需要查詢DUAL - 從mytable中選擇'Y',其中parent_id =:id AND ROWNUM = 1'給出相同的結果。 – 2010-01-26 08:47:16

+0

是的 - 只是不喜歡「ROWNUM = 1」 - 並不像EXISTS查詢那樣透明。儘管如此。 – 2010-01-26 11:54:04

2

首先,您需要mytable.parent_id上的索引。

這應該使您的查詢速度不夠快,即使是大表(除非也有很多行與同PARENT_ID)。

如果沒有,你可以寫

select 1 from mytable where parent_id = :id and rownum < 2 

這將返回一個包含1單行,或沒有行的。它不需要對行進行計數,找到一個然後退出。但是這是Oracle特有的SQL(因爲rownum),你不應該這樣做。

+0

+1對於索引推薦 – 2010-01-25 11:13:52

+2

我想去一個EXISTS查詢我認爲 - 對需求更加透明:select 2 from dual where exists(select from mytable where parent_id =:id) – 2010-01-25 13:00:17

0

對於DB2有類似select * from mytable where parent_id = ? fetch first 1 row only。我認爲oracle有類似的東西存在。

+1

所有SQl方言不同 - 你不能認爲有類似的東西例如Oracle有rownum,在Sybase中並不存在,我認爲在DB2 – Mark 2010-01-25 10:25:59

+2

中,rownum概念是我稱之爲「類似」的概念,因爲它涵蓋了相同的用例,即獲得最前n個記錄(http://www.petefreitag。 com/item/59.cfm) – bertolami 2010-01-25 10:39:21

+0

re:top n。 rownum的一個問題是,它在任何排序完成之前都會被評估,因此它不是真正的「頂級」n。 – Thilo 2010-01-25 10:54:27

4

有沒有實質性差別:

select 'y' 
    from dual 
where exists (select 1 
       from child_table 
       where parent_key = :somevalue) 

select 'y' 
    from mytable 
where parent_key = :somevalue 
    and rownum = 1; 

...至少在Oracle10gR2以上。 Oracle在該版本中足夠聰明,可以執行FAST DUAL操作,從而將任何真正的活動歸零。如果這是一個考慮因素,第二個查詢將更容易移植。

真正的性能區別在於parent_key列是否被索引。如果不是,那麼你應該運行類似:

select 'y' 
    from dual 
where exists (select 1 
       from parent_able 
       where parent_key = :somevalue) 
5

SELECT COUNT(*)應lighteningly快,如果你有一個指標,如果你不這樣做,允許數據庫中止第一場比賽勝利之後沒什麼幫助。

但既然你問:

boolean exists = session.createQuery("select parent_id from Entity where parent_id=?") 
         .setParameter(...) 
         .setMaxResults(1) 
         .uniqueResult() 
       != null; 

(可以預料的一些語法錯誤,因爲我沒有休眠來測試針對此計算機上)

對於Oracle,maxResults,則翻譯成rownum通過休眠。

至於uniqueResult()的功能,請閱讀它的JavaDoc!使用uniqueResult而不是list()不會影響性能;如果我沒有記錯,執行uniqueResult委託給list()。

+0

+1 for setMaxResults – Thilo 2010-01-26 00:50:59

0

如果任何記錄存在,否則爲0這個查詢將返回1:

SELECT COUNT(1) FROM (SELECT 1 FROM mytable WHERE ROWNUM < 2); 

當你需要檢查表數據統計它可以幫助,無論表規模和任何性能問題。

相關問題