簡體   English   中英

mysql查詢速度 - 選擇每3行的最大值

[英]mysql speed of query - selecting max value of every 3 rows

我有一張包含價格信息的表格。 我需要選擇每三行的最大值。 例:

Table `daily_high`
 ____ _______
| ID | HIGH  |
| 1  | 24.65 |
| 2  | 24.93 |
| 3  | 26.02 |
| 4  | 25.33 |
| 5  | 25.16 |
| 6  | 25.91 |
| 7  | 26.05 |
| 8  | 28.13 |
| 9  | 27.07 |
|____|_______|


Desired output to new table (ID will be auto-increment so don't assume an association exists between this ID 1 and the daily_high ID 1:
 ____ ___________
| ID | 3MaxHIGH  |
|____|___________|
| 1  | 26.02     |
| 2  | 25.91     |
| 3  | 28.13     |
|____|___________|

我想比較ID 1,2和3來確定它們之間的高值。 然后,一旦我比較了1-3,我想繼續進行4到6,然后是7到9等,直到我為表中包含的所有值(目前大約400,000個值)完成此操作。 我編寫了使用的代碼

SELECT max(HIGH) FROM daily_high as dh1 JOIN (SELECT max(HIGH) FROM daily_high WHERE id >= dh1 AND id < (dh1.id + 3))

這有效,但速度非常慢。 我已經嘗試使用SELECT語句,我在其中標識要顯示的列值,這意味着在查詢的SELECT和FROM部分之間。

我試圖使用JOIN將所有3行連接到同一個表上進行比較,但它也非常慢。 慢了我的意思是在不到10秒的時間內收集20行的信息。 這意味着查詢在9.65879893303秒內分析了60行(20組3個)(我沒有這樣做,我用microtime()來計算它。

任何人都有任何建議比我更快的代碼?

請記住,我的實際表格與我上面發布的表格不同,但概念是相同的。

謝謝你的幫助。

如果你持續識別,你可以做到這一點

SELECT floor(id/3) as range, max(HIGH) FROM daily_high GROUP BY range;

為什么不使用DIV運算符對聚合進行分組:

SELECT (id-1) DIV 3 + 1 AS ID, MAX(high) AS 3MaxHIGH 
FROM daily_high 
GROUP BY (id-1) DIV 3

此查詢給出相同的結果。

ID  3MaxHIGH
1   26.02
2   25.91
3   28.13

我無法運行您的查詢,我相信這個更快。

UPD :要確保您擁有范圍的有效組,請使用以下查詢:

select id, high, (id-1) div 3 + 1 from daily_high

結果:

id  high    (id-1) div 3 + 1
1   24.65   1
2   24.93   1
3   26.02   1
4   25.33   2
5   25.16   2
6   25.91   2
7   26.05   3
8   28.13   3
9   27.07   3

富勒以一個例子回答。 以下代碼將執行我認為您想要的操作。

SELECT FLOOR((row - 1) / 3), MAX(Sub1.high)
FROM (SELECT @row := @row + 1 as row, daily_high.*
FROM daily_high, (SELECT @row := 0) r) Sub1
GROUP BY FLOOR((row - 1) / 3) 
ORDER BY Sub1.ID

以下查詢在測試表上為我工作。 也許不是最好的,但其他解決方案在我的測試表上失敗了。

這確實要求ID是順序的。 另外一定要把一個索引放在High以及速度上。

SELECT FLOOR(T1.Id/3)+1 AS Id, ROUND(GREATEST(T1.High, T2.High, T3.High),2) AS High FROM `daily_high` T1, `daily_high` T2, `daily_high` T3
WHERE T2.Id=T1.Id+1 
AND T3.Id=T2.Id+1
AND MOD(T1.Id, 3)=1
logic: if(id is divisible by 3, id/3-1, id/3)

select if(mod(id,3) = 0,floor(id/3)-1,floor(id/3)) as group_by_col , max(HIGH)
FROM daily_high GROUP BY group_by_col;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM