2013-11-20 69 views
0

目前,我有以下查詢需要較長的時間來執行SQL查詢優化:比較相鄰行

SELECT * FROM Table t1 
WHERE EXISTS 
(
    SELECT * FROM Table t2 
    WHERE 
    (
     t1.Key = t2.Key - 1 
     AND t1.Foo = 1 
     AND t2.Bar = 0 
    ) 
) 

Key是主鍵字段。我只比較相鄰的行,所以直覺上看,最快的實現方式是比較所有相鄰的行,N-1表示。我的查詢的工作方式,我認爲它可能會比較每行與Table中的每一行,即採取N * N比較。

有沒有更好的方法來編寫查詢?

+0

'有沒有更好的方法來編寫查詢?'不,它是完美的,典型的DBMS不會執行N * N行 - 比較,而是使用某種合併加入。在這種情況下,問題比選擇中的解決方案要好d答案,IMO。 – wildplasser

+0

BTW:請使用理智_metasyntactic_名稱;無論是富/酒吧或蘋果/橙色或'my_table'或其他。但**不要**命名你的表'表'和你的鑰匙'鑰匙'。你不會將你的孩子命名爲「孩子」,是嗎? – wildplasser

+0

我的DBMS似乎沒有合併連接。布拉德的回答比這個速度快4倍。 – rwolst

回答

2

如何像:

Select t1.* 
From table t1 
inner join table t2 
on t1.key = t2.key - 1 
where t1.Foo = 1 
and t2.Bar = 0 

我在測試這一個表有幾百萬行,它運行在大約10秒內

+0

這是錯誤的,因爲這也會從t2別名中選擇列。 (或者它是一張桌子?)。 (另:從表t1的語法是錯誤的) – wildplasser

+0

我修正了問題1,我不明白問題2.當然,在某些數據庫中,「表」是一個關鍵字,但似乎這並不妨礙提問者。 – Brad

+0

好吧,看起來OP將他的表格命名爲「table」,這相當愚蠢的恕我直言。你會不會給你的孩子命名爲「孩子」?順便說一句:我不認爲't1。*'語法是標準的ANSI-SQL,但是它是一些實現使用的擴展。 (我仍然認爲'EXISTS(..)'版本更清潔,因爲它避免了將外部查詢中的t2別名_leaking_) – wildplasser

1

試試這個:

SELECT t1.* FROM Table t1 
LEFT JOIN Table t2 ON (t1.Key = t2.Key-1) 
WHERE t1.Foo=1 AND t2.Bar = 0 

LEFT JOIN基本上過濾掉表B中不存在的行(在這種情況下 - T2)。經驗法則是避免子查詢,如果它們不是必需的,或者如果您不確定它們將執行得很好(快速)。

另外,還要確保你使用正確的指數化(除了關鍵,我會做一個索引上對字段:(美孚,酒吧)