2009-09-02 43 views
0

考慮下面的代碼片段:如何優化這些查詢?

$beat = date('B'); // 1 beat = 86.4 seconds, 1000 beats = 1 day 
$total = 'SELECT COUNT(id) FROM ads WHERE featured = 1;'; // number of featured ads 
$current = 'SELECT * FROM ads WHERE featured = 1 ORDER BY id ASC LIMIT 1 OFFSET ' . ($beat % $total) . ';'; // current featured ad 

基本上這個週期低谷的所有功能的廣告給他們中的每一個節拍,他們將給予特別的亮點(86.4秒)窗口,例如:

$beat  $total   $current 

0   3   0 
1   3   1 
2   3   2 
3   3   0 
4   3   1 
5   3   2 
6   3   0 
7   3   1 

這工作得很好,但我想知道是否有可能消除$總查詢的需要,並使用一個查詢完成相同的操作。

我沒有看到無論如何不使用子查詢,但仍然,我想聽聽你的意見。

+0

不應該最後一個查詢只選擇其中特徵= 1的那個? – 2009-09-02 13:35:40

+0

鑑於數據集,你可以用3替換$ total。 也許你想給一個更多樣化的例子? –

+0

@lanut:對不起,現在修好了。 –

回答

1

不,這是不可能的。 mysql在LIMIT子句中需要顯式常量值。你不能在LIMIT子句中進行計算。

+0

你能提出任何其他解決方法嗎?爲此僅做兩個查詢似乎太麻煩。 –

2
$current = 'SELECT *, FOUND_ROWS(id) as num FROM ads WHERE featured = 1 ORDER BY id ASC LIMIT 1 OFFSET MOD(' . $beat . ', num)'; 
+0

LIMIT 1子句不會影響COUNT函數嗎? –

+0

是的,謝謝你的提示。應該使用FOUND_ROWS()而不是 – stefita

+1

mysql在LIMIT子句中需要顯式常量值。你不能在LIMIT子句中進行計算。 – longneck

-1

您無法優化查詢。但是你可以優化算法。可能你需要這樣做,但是...))

如果$total >= 1000你永遠不會顯示一些廣告。無論如何,有些廣告的展示次數會比其他廣告多。

long timestamp = ... // standard timestamp in millis 
long period = 86400; // millis 
long total = ... // you total query 
long offset = (timestamp/period) % total; 
current = ... // you last query, but with my offset 
+0

這是如何被認定爲優化的?我仍然必須做2個查詢,算法基本相同,我忽略了$ total的1000個限制,因爲它是微不足道的,解決了這個問題。 –

+0

我的第一句話:「你無法優化查詢」。所以,這不是最優化。 –