我對MySQL非常陌生,也感謝來自您的更有經驗的人士提供的大力支持,這裏我一直在努力奮鬥,同時在此過程中學習了很多。如何簡化/提高此MySQL查詢的性能?
我有一個查詢,正是我想要的。但是,它看起來非常混亂,我確信必須有一種方法來簡化它。
該查詢如何針對性能進行改進和優化?
非常感謝
$sQuery = "
SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
FROM $sTable b
LEFT JOIN (
SELECT COUNT(*) AS projects_count, a.songs_id
FROM $sTable2 a
GROUP BY a.songs_id
) bb ON bb.songs_id = b.songsID
LEFT JOIN (
SELECT AVG(rating) AS rating, COUNT(rating) AS ratings_count, c.songid
FROM $sTable3 c
GROUP BY c.songid
) bbb ON bbb.songid = b.songsID
LEFT JOIN (
SELECT c.songid, c.userid,
CASE WHEN EXISTS
(
SELECT songid
FROM $sTable3
WHERE songid = c.songid
) Then 'User Voted'
else
(
'Not Voted'
)
end
AS voted
FROM $sTable3 c
WHERE c.userid = $userid
GROUP BY c.songid
) bbbb ON bbbb.songid = b.songsID
編輯:這是一個什麼樣的查詢做了說明: -
我有三個表:
$穩定=歌曲表(songid,mp3link,作品,useruploadid 等)
$ sTable2 =的項目鏈接到他們(專案編號, songid,項目名稱等)的歌曲表
$ sTable3 =歌曲排行榜(songid,用戶ID,等級)
所有這些數據都會輸出到JSON數組中,並顯示在我的應用程序的表中,以提供歌曲列表以及項目和評分數據。
查詢本身並按此順序如下: -
- 收集來自$穩定的所有行
- 加入到$ sTable2上songsID並在此表中具有計數的行(項目)的數量同樣songsID
- 加入到$ stable3上songsID並在此表中具有相同songsID
- 此時的作品出列「評級」的平均同時也計算在$ sTable3行具有總數相同的歌曲ID來提供總票數。
- 最後,它會對所有這些行執行檢查,以查看每個行的$ userid(它是包含登錄用戶的ID的變量)是否與$ sTable3中的'userid'存儲匹配,以檢查用戶已經對給定的歌曲ID進行了投票。如果匹配,則返回「用戶投票」,否則返回「未投票」。它將它作爲一個單獨的列輸出到我的JSON數組中,然後在我的應用程序中檢查客戶端並添加一個類。
如果有任何更多的細節需要任何人,請讓我知道。謝謝大家。
編輯:
由於Aurimis'優第一次嘗試我將結束在一個更簡單的解決方案。
這是我嘗試基於該建議的代碼。
SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
FROM
(SELECT
$sTable.songsID, COUNT(rating) AS ratings_count,
AVG(rating) AS ratings
FROM $sTable
LEFT JOIN $sTable2 ON $sTable.songsID = $sTable2.songs_id
LEFT JOIN $sTable3 ON $sTable.songsID = $sTable3.songid
GROUP BY $sTable.songsID) AS A
LEFT JOIN $sTable3 AS B ON A.songsID = B.songid AND B.userid = $userid
但是有幾個問題。我不得不刪除你的答案的第一行,因爲它造成了500內部服務器錯誤:
IF(B.userid = NULL, "Not voted", "User Voted") AS voted
顯然,現在的「投檢查」功能將丟失。
此外,更重要的是它不返回在我的數組中定義的所有列,只有歌曲ID。我的JSON在'字段列表'中返回未知列'song_name' - 如果我從$ aColumns數組中刪除它,它當然會移動到下一個。
我在我的腳本的開頭定義了我的列,因爲此數組用於篩選和放置JSON編碼的輸出。這是$ aColumns的定義: - 。
$aColumns = array('songsID', 'song_name', 'artist_band_name', 'author', 'song_artwork', 'song_file', 'genre', 'song_description', 'uploaded_time', 'emotion', 'tempo', 'user', 'happiness', 'instruments', 'similar_artists', 'play_count', 'projects_count', 'rating', 'ratings_count', 'voted');
爲了快速測試我修改了子查詢中的第一行查詢的其餘部分選擇$穩定*而不是$ sTable.songsID(記得$穩定是歌曲表)
然後...查詢顯然有效,但當然表現糟糕。但是,只能從5000首歌曲測試數據集中返回24首歌曲。因此我將你的第一個'JOIN'改爲'LEFT JOIN',以便所有5000首歌曲都被返回。爲了說明查詢需要返回歌曲表中的所有行,但需要爲每首歌曲的項目和評分表添加各種額外的數據位。
所以......我們到了那裏,我確信這是一個更好的方法,它只是需要一些修改。感謝你的幫助到目前爲止Aurimis。
似乎誰寫的查詢的人是不是新來的MySQL – newtover
我通過「谷歌搜索」,問各種問題在這裏,並讀了自己寫的很多。然而,我本質上已經將幾件作品拼湊成一個「工作」查詢來實現我想要的。雖然我理解查詢的每個部分都做了什麼以及它爲什麼起作用,但我沒有經驗來知道我是否以有效的方式執行此操作。我從其他語言的經驗中得出的結論告訴我,我不是。因此,我會歡迎更有經驗的MySQL開發人員的建議。 :) – gordyr
你能描述一下預期的結果嗎? – Peter