我試圖運行在Oracle中下面的SQL語句,它需要年齡運行:優化運行緩慢甲骨文很快地運行SQL Server的SELECT查詢
SELECT orderID FROM tasks WHERE orderID NOT IN
(SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL)
如果我只運行子部分即IN子句,在甲骨文運行速度很快的,即
SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL
爲什麼整個聲明採取的Oracle這麼長的時間?在SQL Server中,整個語句運行得很快。
另外還有一個更簡單/不同/更好的SQL語句,我應該使用?
有關該問題的更多的細節:
- 每個訂單是由許多任務
- 每個訂單將被分配(一個或多個它的任務將有工程師1和engineer2設置)或順序可以未分配(其所有任務對於工程師字段都爲空值)
- 我正在嘗試查找所有未分配的orderID。
爲了防萬一,它有什麼區別,表中有〜120K行,每個訂單有3個任務,所以〜40K個不同的訂單。
迴應的答案:
- 我寧願這兩個SQL Server和Oracle在工作的SQL語句。
- 這些任務只有orderID和taskID上的索引。
- 我嘗試了這個聲明的NOT EXISTS版本,但是在我取消它之前運行了3分鐘。也許需要一個JOIN版本的聲明?
- 還有一個「orders」表以及orderID列。但是我試圖通過不將它包含在原始SQL語句中來簡化問題。
我想在原來的SQL語句中,每次在SQL語句的第一部分中都會運行子查詢 - 儘管它是靜態的,只需要運行一次?
執行
ANALYZE TABLE tasks COMPUTE STATISTICS;
了我原來的SQL語句執行速度更快。
雖然我仍然很好奇爲什麼我必須這樣做,如果/當我需要再次運行它時?
根據統計甲骨文是 需要確定效率的不同的執行計劃 基於成本 optimzer信息:爲 例如,rowsin表, 行的平均寬度的數量,最高 每列最低值,每列不同值 ,集羣 索引等因素
在一個小型數據庫中,您只需設置 就可以每晚收集統計數據 ,並保持獨立。其實這是 默認在10g以下。對於較大的 實現,您通常必須以 衡量執行的穩定性 計劃與數據 更改的方式,這是一個棘手的平衡。
Oracle還有一個稱爲其用於 樣品表來確定在執行時相關 統計 「動態採樣」功能。這是 更經常與數據使用 倉庫,其中 採樣的開銷超過了 長時間運行的查詢的潛在性能提升。
我永遠不會明白爲什麼程序員經常把DISTINCT放在他們的IN子句中。 (1,1,1,2,2,2,7)是7?是5?如果我的列表是(1,2,7),答案不會改變。當我在Oracle中運行它時,它忽略了獨特的... CBO意識到沒有價值。 – 2008-10-24 21:38:16