2012-08-28 42 views
2

當我們在一個查詢中連接了多於2-3個表時,並且如果我們在所有表中有一個共同的列,那麼當我們在在多個表上連接時的SQL查詢性能

,時會有任何差異
  1. 指定所有表格中公共列的值。

    爲前:

    select e.* 
    from emp e, dept d 
    where e.deptno = 10 
    and d.deptno = 10; 
    
  2. 給定值的公共列中的一個,並加入與其他

    爲前:

    select e.* 
    from emp e, dept d 
    where e.deptno = 10 
    and d.deptno = e.deptno; 
    

之所以問這個問題是,我有一個查詢(成本是17),當我按照例1指定值時會執行,但會被掛起從不執行,如果我加入列中的例子2.

請幫我理解這一點。

回答

2

它取決於索引。如果您在這兩個表中的某一列上都有索引,則應該沒有區別。但是,如果沒有,第二個可能會慢得多。

Deptno是唯一的嗎? (在任何一個表中)。如果它是製作的,那麼你可以這樣設置索引。

+0

deptno不是唯一的,但是是複合PK的一部分,因此索引存在於該列上。我甚至收集了統計數字,但仍然沒有幫助。 – Savitha

+0

@Savitha它是複合PK中的第一列嗎?因爲否則它什麼都不會做。 – Ariel

+0

@Savitha等 - 這不是唯一的?在兩個表中?至少它們中的一個必須是唯一的,否則你的查詢將會爆炸成大量的行。 – Ariel

1

我不同意關於唯一性問題。 DEPTNO不必在任何一個表上都是唯一的,但如果不是這種查詢可能響應速度很慢。關於索引 - 是的,應該有單獨的DEPTNO索引,或者DEPTNO作爲兩個表上的第一個字段。沒有這樣的索引,查詢將會非常緩慢。

關於查詢結構 - 我喜歡ANSI查詢語法:

SELECT e.* 
    FROM EMP e 
    INNER JOIN DEPT d 
    ON (d.DEPTNO = e.DEPTNO) 
    WHERE e.DEPTNO = 10 

我不明白爲什麼被加入了DEPT表作爲你不是在它使用的任何數據,除非有一些DEPTNO = 10可能在DEPT中沒有行。假設一排DEPT與DEPTNO存在= 10你會通過執行

SELECT e.* 
    FROM EMP e 
    WHERE e.DEPTNO = 10 

無需支付從EMP加入DEPT到每個結果行的成本得到同樣的結果 - 從,然後轉身丟棄該數據DEPT。

分享和享受。

+0

DEPTNO必須是唯一的,以避免笛卡爾連接,其中一個表中匹配10的行數乘以另一個表中的數量。儘管只有數千個數據庫,但這可能會導致返回數百萬行。有時你真的想要這樣做,但在這種情況下不需要。 – Ariel

+0

@Ariel - 我同意這隻適用於DEPTNO在某個地方是唯一的(我當然認爲它在DEPT表中是唯一的),但即使產生了笛卡爾連接,查詢仍然會正確執行。我想這個查詢可以改寫爲SELECT e。* from(SELECT DISTINCT DEPTNO FROM DEPT)d INNER JOIN EMP e ON(e.DEPTNO = d.DEPTNO)WHERE d.DEPTNO = 10' - 但我仍然不知道爲什麼DEPT首先加入。所以它... –

+0

這不是一個工作的問題,這是一個速度問題。 – Ariel