2013-01-08 63 views
2

我有形式的查詢:SQLite的順序

SELECT akey, avalue, expensiveop(akey) FROM atable WHERE avalue < SOME_CONSTANT; 

似乎expensiveop() - 這是一個用戶定義的函數,它的時間有相當多execute- -gets調用表中的所有行。出於性能原因,我只希望它爲結果集中的每一行執行一次。

我嘗試以下方法,這似乎並沒有有所作爲:

SELECT akey, avalue, expensiveop(akey) FROM (SELECT * FROM atable WHERE avalue < SOME_CONSTANT) 

任何想法?

+0

見* 9.0查詢展平*在http://www.sqlite.org/optoverview.html(和搜索CROSS JOIN在想法的同一頁) – biziclop

回答

0

你可以閱讀有關的SQLite的優化​​,在此頁面,尤其是查詢展平部分: http://www.sqlite.org/optoverview.html#flattening

它包含的19個限制條件所有這些都必須得到滿足,以允許查詢展平發生的列表。選擇一個,並做到這一點說的確切oppposite,例如一些隨機的例子(未經測試):

SELECT akey, avalue, expensiveop(akey) 
FROM (SELECT * FROM atable WHERE avalue < SOME_CONSTANT LIMIT 99999999) 
LIMIT 99999999 

SELECT akey, avalue, expensiveop(akey) FROM 
(SELECT * FROM atable WHERE avalue < SOME_CONSTANT 
UNION 
SELECT * FROM atable WHERE 0 GROUP BY avalue) 

SELECT akey, avalue, expensiveop(akey) FROM 
(SELECT * FROM atable WHERE avalue < SOME_CONSTANT LIMIT -1 OFFSET 0) 
+0

我喜歡第三個,但我認爲這個語法是無效的。我認爲子查詢的末尾需要是「LIMIT -1 OFFSET 0」 – laslowh

+0

的確,OFFSET需要LIMIT:http://www.sqlite.org/lang_select.html我不知道SQLite是否優化了無限制+偏移量0或不。 – biziclop

+0

它似乎有我正在尋找的效果,至少在3.7.9。但是,我可以看到未來會發生變化。 – laslowh

0

的解決方法,一個想法:

SELECT akey, avalue, CASE avalue < SOME_CONSTANT WHEN 0 THEN NULL ELSE expensiveop(akey) END FROM avalue WHERE avalue < SOME_CONSTANT 
0

另一個想法是:

SELECT akey, avalue, expensiveop(akey) 
FROM atable 
WHERE avalue < SOME_CONSTANT 
group by akey, avalue 

SQL應該執行wheregroup by之前做昂貴的操作,因爲它使用的是聚集「關鍵」。如果查詢有類似min(expensiveop(akey))那麼它會爲每一行執行它。