1. 程式人生 > >關聯查詢和多次查詢的點 以及 MySQL慢查詢優化 EXPLAIN詳解

關聯查詢和多次查詢的點 以及 MySQL慢查詢優化 EXPLAIN詳解

        對於欄位比較多的表,如果有些欄位的使用頻率很低,可以將這些欄位分離出來形成新表。因為當一個表的資料量很大時,會由於使用頻率低的欄位的存在而變慢。2. 增加中間表        對於需要經常聯合查詢的表,可以建立中間表以提高查詢效率。通過建立中間表,把需要經常聯合查詢的資料插入到中間表中,然後將原來的聯合查詢改為對中間表的查詢,以此來提高查詢效率。3. 增加冗餘欄位        設計資料庫表時應儘量遵循正規化理論的規約,儘可能減少冗餘欄位,讓資料庫設計看起來精緻、優雅。但是合理加入冗餘欄位可以提高查詢速度。 切分查詢        比如我們要刪除舊的資料,可能需要一次性刪除很多資料會鎖住很多資料、佔滿整個事務日誌、耗盡系統資源、阻塞很多小的但重要的查詢。將一個大的DELETE語句切成多個較小的查詢可以儘可能小的影響MySQL效能,同時還可以減少MySQL複製的延遲,如下:        DELETE FROM table WHERE create_date < NOW();         替換為        rows_affected = 0        do {             rows_affected = do_query(                "DELETE FROM table WHERE create_date < NOW() LIMIT 10000"                )        } while rows_affected > 0        一次刪除一萬行資料一般來說是一個比較高效而且對伺服器影響也最小的做法,如果每次暫停一會會更好。分解關聯查詢
        有時候將一個大的查詢分解為多個小查詢是很有必要的。        很多高效能的應用都會對關聯查詢進行分解,就是可以對每一個表進行一次單表查詢,然後將查詢結果在應用程式中進行關聯,很多場景下這樣會更高效,例如:        SELECT * FROM tag         JOIN tag_post ON tag_id = tag.id        JOIN post ON tag_post.post_id = post.id        WHERE tag.tag = 'mysql';        分解為:        SELECT * FROM tag WHERE tag = 'mysql';        SELECT * FROM tag_post WHERE tag_id = 1234;        SELECT * FROM post WHERE post.id in (123,456,567);        有很多場景都可以使用:比如當應用能夠方便地快取單個查詢的結果的時候、當可以將資料分佈到不同MySQL伺服器上的時候、當能夠使用IN()的方式代替關聯查詢的時候、當查詢中使用同一個資料表的時候。優化LIMIT分頁
        在分頁偏移量很大的時候,如LIMIT 10000,20這樣的查詢,MySQL需要查詢10020條記錄然後只返回最後20條,前面10000條記錄都被拋棄,這樣代價非常高。        優化的最簡單的辦法就是儘可能地使用索引覆蓋掃描,而不是查詢所有的列。然後根據需要做一次關聯操作再返回所需的列,對於偏移量很大的時候,這樣做的效率回提升很大,如下:        SELECT file_id, description FROM film ORDER BY title LIMIT 50, 5;        修改為:        SELECT film.film_id, film.description FROM film 
        INNER JOIN (SELCT film_id FROM film ORDER BY title LIMIT 50, 5) AS lim USING(film_id);        這裡“延遲關聯”將大大提升查詢效率,它讓MySQL掃描儘可能少的頁面,獲取需要訪問的記錄後在根據關聯列回原表查詢需要的所有列。