關于mysql處理百萬級以上的數據時如何提高其查詢速度的方法
為縉云等地區用戶提供了全套網頁設計制作服務,及縉云網站建設行業解決方案。主營業務為成都網站設計、做網站、縉云網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
最近一段時間由于工作需要,開始關注針對Mysql數據庫的select查詢語句的相關優化方法。
由于在參與的實際項目中發現當mysql表的數據量達到百萬級時,普通SQL查詢效率呈直線下降,而且如果where中的查詢條件較多時,其查詢速度簡直無法容忍。曾經測試對一個包含400多萬條記錄(有索引)的表執行一條條件查詢,其查詢時間竟然高達40幾秒,相信這么高的查詢延時,任何用戶都會抓狂。因此如何提高sql語句查詢效率,顯得十分重要。以下是網上流傳比較廣泛的30種SQL查詢語句優化方法:
1、應盡量避免在 where 子句中使用!=或操作符,否則將引擎放棄使用索引而進行全表掃描。
2、對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
3、應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0
4、盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20
5、下面的查詢也將導致全表掃描:(不能前置百分號)
select id from t where name like ‘%c%’
若要提高效率,可以考慮全文檢索。
6、in 和 not in 也要慎用,否則會導致全表掃描,如:
select id from t where num in(1,2,3)
對于連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
7、如果在 where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然 而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:
select id from t where num=@num
可以改為強制查詢使用索引:
select id from t with(index(索引名)) where num=@num
8、應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where num/2=100
應改為:
select id from t where num=100*2
9、應盡量避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where substring(name,1,3)=’abc’–name以abc開頭的id
select id from t where datediff(day,createdate,’2005-11-30′)=0–’2005-11-30′生成的id
應改為:
select id from t where name like ‘abc%’
select id from t where createdate=’2005-11-30′ and createdate’2005-12-1′
10、不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
11、在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統使用該索引,否則該索引將不會被使 用,并且應盡可能的讓字段順序與索引順序相一致。
12、不要寫一些沒有意義的查詢,如需要生成一個空表結構:
select col1,col2 into #t from t where 1=0
這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣:
create table #t(…)
13、很多時候用 exists 代替 in 是一個好的選擇:
select num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
14、并不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引,如一表中有字段 sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
15、索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。
16.應盡可能的避免更新 clustered 索引數據列,因為 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新 clustered 索引數據列,那么需要考慮是否應將該索引建為 clustered 索引。
17、盡量使用數字型字段,若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接時會 逐個比較字符串中每一個字符,而對于數字型而言只需要比較一次就夠了。
18、盡可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長字段存儲空間小,可以節省存儲空間,其次對于查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
19、任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
20、盡量使用表變量來代替臨時表。如果表變量包含大量數據,請注意索引非常有限(只有主鍵索引)。
21、避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。
22、臨時表并不是不可使用,適當地使用它們可以使某些例程更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對于一次性事件,最好使 用導出表。
23、在新建臨時表時,如果一次性插入數據量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然后insert。
24、如果使用到了臨時表,在存儲過程的最后務必將所有的臨時表顯式刪除,先 truncate table ,然后 drop table ,這樣可以避免系統表的較長時間鎖定。
25、盡量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那么就應該考慮改寫。
26、使用基于游標的方法或臨時表方法之前,應先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。
27、與臨時表一樣,游標并不是不可使用。對小型數據集使用 FAST_FORWARD 游標通常要優于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括“合計”的例程通常要比使用游標執行的速度快。如果開發時 間允許,基于游標的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。
28、在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每個語句后向客戶端發送 DONE_IN_PROC 消息。
29、盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。
30、盡量避免大事務操作,提高系統并發能力。
你寫代碼的時候注意 HTML格式 和CSS格式。不要把所有內容都寫到同一個DIV中間,這樣東西多的時候就會卡住。要分層次顯示,另外碰到數據庫查詢文字非常多的你還可以使用AJAX 返回數據 這樣HTML就可以很快的顯示 顯示完畢才去讀數據庫這樣速度會快很多。至于樓上說的 緩存 數據庫存儲過程 可以參考一下,不過一般企業站不需要考慮。碰到大站在線100人以上的才會做。
php 高并發解決思路解決方案,如何應對網站大流量高并發情況。本文為大家總結了常用的處理方式,但不是細節,后續一系列細節教程給出。希望大家喜歡。
一 高并發的概念
在互聯網時代,并發,高并發通常是指并發訪問。也就是在某個時間點,有多少個訪問同時到來。
二 高并發架構相關概念
1、QPS (每秒查詢率) : 每秒鐘請求或者查詢的數量,在互聯網領域,指每秒響應請求數(指 HTTP 請求)
2、PV(Page View):綜合瀏覽量,即頁面瀏覽量或者點擊量,一個訪客在 24 小時內訪問的頁面數量
--注:同一個人瀏覽你的網站的同一頁面,只記做一次 pv
3、吞吐量(fetches/sec) :單位時間內處理的請求數量 (通常由 QPS 和并發數決定)
4、響應時間:從請求發出到收到響應花費的時間
5、獨立訪客(UV):一定時間范圍內,相同訪客多次訪問網站,只計算為 1 個獨立訪客
6、帶寬:計算帶寬需關注兩個指標,峰值流量和頁面的平均大小
7、日網站帶寬: PV/統計時間(換算到秒) * 平均頁面大?。╧b)* 8
三 需要注意點:
1、QPS 不等于并發連接數(QPS 是每秒 HTTP 請求數量,并發連接數是系統同時處理的請求數量)
2、峰值每秒請求數(QPS)= (總 PV 數*80%)/ (六小時秒數*20%)【代表 80%的訪問量都集中在 20%的時間內】
3、壓力測試: 測試能承受的最大并發數 以及測試最大承受的 QPS 值
4、常用的性能測試工具【ab,wrk,httpload,Web Bench,Siege,Apache JMeter】
四 優化
1、當 QPS 小于 50 時
優化方案:為一般小型網站,不用考慮優化
2、當 QPS 達到 100 時,遇到數據查詢瓶頸
優化方案: 數據庫緩存層,數據庫的負載均衡
3、當 QPS 達到 800 時, 遇到帶寬瓶頸
優化方案:CDN 加速,負載均衡
4、當 QPS 達到 1000 時
優化方案: 做 html 靜態緩存
5、當 QPS 達到 2000 時
優化方案: 做業務分離,分布式存儲
五、高并發解決方案案例:
1、流量優化
防盜鏈處理(去除惡意請求)
2、前端優化
(1) 減少 HTTP 請求[將 css,js 等合并]
(2) 添加異步請求(先不將所有數據都展示給用戶,用戶觸發某個事件,才會異步請求數據)
(3) 啟用瀏覽器緩存和文件壓縮
(4) CDN 加速
(5) 建立獨立的圖片服務器(減少 I/O)
3、服務端優化
(1) 頁面靜態化
(2) 并發處理
(3) 隊列處理
4、數據庫優化
(1) 數據庫緩存
(2) 分庫分表,分區
(3) 讀寫分離
(4) 負載均衡
5、web 服務器優化
(1) nginx 反向代理實現負載均衡
(2) lvs 實現負載均衡
【1】嘗試這使用網頁靜態化
【2】如果用的第3方虛擬主機,建議換成服務器,使用mancache內存緩存
架構優化涉及到技術、存儲、網絡、服務的選型和構架,盡量使用成熟和現代的開發架構和設計模式。前后端完全分離設計,便于前后端的獨立優化,也更加便于測試工作。
如果你的應用遇到了性能瓶頸,這個時候要考慮的就是優化架構而不是優化代碼本身,因為架構層面的優化效果往往是最顯著的。
架構的優化需要根據自身運營情況來調整,切忌不可按圖索驥提前優化,反而容易得不償失,導致技術成本提高甚至“負優化”
部署環境千萬不要忘記關閉調試模式,這不僅僅是出于性能考慮,更多是基于安全因素。事實上,建議通過環境變量來配置關閉調試模式,這樣部署后不需要更改任何配置文件。
因為調試模式影響日志記錄信息、額外的調試信息和緩存失效,關閉調試模式能夠帶來一定的性能提升
使用多模塊功能會增加文件的 I/O 開銷和額外的配置及檢查,如非必要在規劃你的應用架構的時候盡量考慮使用單一模塊,然后使用控制器分級來解決控制器過多的問題。
使用單一模塊的性能優勢,在部署到 swoole 的時候可以得到更加充分的體現,因為應用文件一旦啟動服務,就會載入內存,而模塊的相關文件則會每次請求重新加載。
在定義路由規則的時候,不要使用數組方式,盡量使用方法注冊路由,并且多使用路由分組(或者資源路由)。分組路由可以減少路由的匹配次數,從而提升路由性能。如果你有多個域名的不同路由,也要按域名規劃使用路由。
盡可能設計在路由中進行當前路由的數據驗證和權限檢查等操作,一方面比較清晰,另外一方面可以盡量把驗證操作提前,而不必等到控制器執行。
在分組比較多的情況下,開啟路由的延遲解析。
如果同一個分組下面有比較多的路由規則,建議合并路由規則
對于 GET 請求的路由,可以設置路由的請求緩存。
部署階段,可以開啟路由緩存。
首先保持良好的開發習慣,了解 Db類和模型的正確使用姿勢 ,數據庫本身的性能優化可以參考 MySQL性能優化的最佳21條經驗 ,下面主要是對框架中數據查詢相關的優化策略。
盡量減少每次請求的查詢次數,并對實時性要求不高的數據查詢合理規劃數據查詢緩存(優先考慮使用 Redis 緩存)
如果使用了關聯查詢, cache 方法只能用于主模型的數據緩存,但你可以使用 Cache 類的 remember 方法進行方便的數據緩存。
盡量減少查詢次數是出于性能考慮,但不是必須,使用最少的查詢不代表性能就一定是最高。一個復雜的 JOIN 查詢性能不見得有兩次簡單的查詢高,而使用簡單的查詢反而更清晰易懂,并且更方便進行數據查詢緩存。
不要總是以為模型的性能一定比 Db 類低,框架的ORM查詢設計經過了較為合理的優化,正確使用模型一樣可以有出色的性能,而且比 Db 查詢要方便很多。
尤其是對于一些復雜的設計來說使用模型關聯顯得比直接用Db更加簡單,例如使用關聯預載入查詢就可以避免 N+1 查詢問題。
如果用 Db 類自己實現的話,費時費力,性能還不一定優。
對于內存開銷比較大的應用,在做大量數據查詢和處理的時候,使用 cursor 方法,可以利用PHP的生成器特性,減少內存占用。
你會發現用戶數據不論是1萬還是10萬級別,內存開銷并沒有大的變化。
涉及到對大量數據的處理,包括數據遷移、批量更新,盡量使用命令行指令運行,否則會因為超時而中斷
可以通過數據集的方法完成的子集或者排序操作不要再次查詢,例如:
利用下面指令在部署后生成字段緩存,可以減少每次數據表的字段查詢開銷。
注意:一旦數據庫的表結構發生變化,必須重新生成。
每次在應用初始化或者模塊初始化的時候會有一定的 I/O 開銷,如果已經開啟 OpCache 的話對性能影響甚微,如果比較在意的也可以通過命令行指令生成配置緩存(包括相關的公共文件和各種定義文件)。
生成應用配置緩存:
生成模塊配置緩存:
注意:一旦配置或者公共文件發生變化,必須重新生成。
類庫映射可以提升類庫的自動加載性能,使用下面的指令可以生成系統類庫和應用類庫的類庫映射(包括 extend 目錄下的類庫)。
vendor 目錄下的類庫可以使用 composer 的 dump-autoload 指令優化加載性能。
該命令把 PSR-0 和 PSR-4 轉換為一個類映射表,來提高類的加載速度。
網站標題:php數據庫性能優化,php 高性能
分享鏈接:http://vcdvsql.cn/article0/hsppoo.html
成都網站建設公司_創新互聯,為您提供云服務器、全網營銷推廣、做網站、自適應網站、響應式網站、營銷型網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯