問題1:數據庫的執行計劃
當我們執行一個查詢時,每次執行查詢時執行計劃是否都會發生變化?
如果是,是否有任何性能下降?
如果否,那麼如果我們改變表中的某些內容,即添加一個索引,數據庫如何知道它可以用來更改執行計劃以加快執行速度?
問題2:
但是,什麼是執行的順序一般在執行連接查詢,尤其是如果有很多連接的(外部,內部,自然的,如果許多外)。
問題1:數據庫的執行計劃
當我們執行一個查詢時,每次執行查詢時執行計劃是否都會發生變化?
如果是,是否有任何性能下降?
如果否,那麼如果我們改變表中的某些內容,即添加一個索引,數據庫如何知道它可以用來更改執行計劃以加快執行速度?
問題2:
但是,什麼是執行的順序一般在執行連接查詢,尤其是如果有很多連接的(外部,內部,自然的,如果許多外)。
你必須在高速緩存最多兩個方案(一個並行,一個非平行)。然後,該計劃與每個用戶的執行上下文一起使用。More info in my answer here
SQL是聲明。這意味着你告訴引擎你想要什麼,優化器制定出最好的計劃(在理性的情況下,可能需要2周才能制定出最好的計劃)。這就是爲什麼你可以用許多不同的方式重寫查詢來得到相同的答案。
與關於RDBMS的任何規則一樣,也有例外。對於複雜的查詢,優化程序不會經歷每個排列,因此JOIN順序可能很重要:它取決於優化程序何時決定它有足夠的時間...
(這裏假設SQL Server中,你沒有指定...)
執行計劃被緩存,併爲您的參數化查詢的程度,可重複使用。
當您修改基礎表或索引時,SQL Server知道這些事情與緩存執行計劃的修改日期,並且可以重新評估新條件的查詢。更新統計數據時同樣的事情......有時候實際的數據驅動計劃,而不僅僅是表/索引設計。
連接不是基於內部對外部的順序完成的,而是基於優化器認爲會導致查詢執行得最快的內容。細節會因數據庫而異。但基本上,查詢優化器會嘗試優化索引的使用。
假設你有如下查詢:
select a.foo, b.bar
from a
join b on b.b_id=a.b_id
where a.some_number=42;
現在,假設你有b.b_id唯一索引,但在a.some_number沒有索引。
查詢優化器然後有兩個選擇:它可以在b上執行全文序列讀取,然後對於每個b在b_id和some_number = 42上尋找匹配時執行全文序列讀取。這是讀取a^b記錄。或者它可以在查找some_number = 42時執行全文順序讀取,然後對於每個可以使用索引快速查找b匹配b_id的記錄。即讀取* 2條記錄。顯然第二個計劃好多了,所以這就是它會選擇的。
隨着您添加更多表格,計算變得更加複雜,但原理相同。使用其他表中找到的值進行快速索引讀取的聯接稍後將在完成其他表的讀取後完成。通常首先讀取必須依次讀取的表格,無論讀取是基於常量還是基於其他記錄的值。
@JPro:並不是每個人都對每個數據庫都有這方面的知識。請考慮你所問的人。 – 2009-10-21 16:17:19