本文目錄一覽:
php+mysql優化,百萬至千萬級快速分頁mysql性能到底能有多高
php+Mysql 優化,百萬至千萬級快速分頁
MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考這個問題還是從前天開始。有過痛苦有過絕望,到現在充滿信心!MySql 這個數據庫絕對是適合dba級的高手去玩的,一般做一點1萬篇新聞的小型系統怎麼寫都可以,用xx框架可以實現快速開發。可是數據量到了10萬,百萬至千萬,他的性能還能那麼高嗎?一點小小的失誤,可能造成整個系統的改寫,甚至更本系統無法正常運行!好了,不那麼多廢話了。用事實說話,看例子:
數據表 collect ( id, title ,info ,vtype) 就這4個字段,其中 title 用定長,info 用text, id 是逐漸,vtype是tinyint,vtype是索引。這是一個基本的新聞系統的簡單模型。現在往裏面填充數據,填充10萬篇新聞。
最後collect 為 10萬條記錄,數據庫表佔用硬盤1.6G。OK ,看下面這條sql語句:
select id,title from collect limit 1000,10; 很快;基本上0.01秒就OK,再看下面的
select id,title from collect limit 90000,10; 從9萬條開始分頁,結果?
8-9秒完成,my god 哪出問題了????其實要優化這條數據,網上找得到答案。看下面一條語句:
select id from collect order by id limit 90000,10; 很快,0.04秒就OK。為什麼?因為用了id主鍵做索引當然快。網上的改法是:
select id,title from collect where id=(select id from collect order by id limit 90000,1) limit 10;
這就是用了id做索引的結果。可是問題複雜那麼一點點,就完了。看下面的語句
select id from collect where vtype=1 order by id limit 90000,10; 很慢,用了8-9秒!
到了這裡我相信很多人會和我一樣,有崩潰感覺!vtype 做了索引了啊?怎麼會慢呢?vtype做了索引是不錯,你直接 select id from collect where vtype=1 limit 1000,10; 是很快的,基本上0.05秒,可是提高90倍,從9萬開始,那就是0.05*90=4.5秒的速度了。和測試結果8-9秒到了一個數量級。從這裡開始有人提出了分表的思路,這個和discuz 論壇是一樣的思路。思路如下:
建一個索引表: t (id,title,vtype) 並設置成定長,然後做分頁,分頁出結果再到 collect 裏面去找info 。 是否可行呢?實驗下就知道了。
10萬條記錄到 t(id,title,vtype) 里,數據表大小20M左右。用
select id from t where vtype=1 order by id limit 90000,10; 很快了。基本上0.1-0.2秒可以跑完。為什麼會這樣呢?我猜想是因為collect 數據太多,所以分頁要跑很長的路。limit 完全和數據表的大小有關的。其實這樣做還是全表掃描,只是因為數據量小,只有10萬才快。OK,來個瘋狂的實驗,加到100萬條,測試性能。
加了10倍的數據,馬上t表就到了200多M,而且是定長。還是剛才的查詢語句,時間是0.1-0.2秒完成!分表性能沒問題?錯!因為我們的limit還是9萬,所以快。給個大的,90萬開始
select id from t where vtype=1 order by id limit 900000,10; 看看結果,時間是1-2秒!
why 分表了時間還是這麼長,非常之鬱悶!有人說定長會提高limit的性能,開始我也以為,因為一條記錄的長度是固定的,mysql 應該可以算出90萬的位置才對啊? 可是我們高估了mysql 的智能,他不是商務數據庫,事實證明定長和非定長對limit影響不大?怪不得有人說 discuz到了100萬條記錄就會很慢,我相信這是真的,這個和數據庫設計有關!
難道MySQL 無法突破100萬的限制嗎???到了100萬的分頁就真的到了極限???
答案是: NO !!!! 為什麼突破不了100萬是因為不會設計mysql造成的。下面介紹非分表法,來個瘋狂的測試!一張表搞定100萬記錄,並且10G 數據庫,如何快速分頁!
好了,我們的測試又回到 collect表,開始測試結論是: 30萬數據,用分表法可行,超過30萬他的速度會慢道你無法忍受!當然如果用分表+我這種方法,那是絕對完美的。但是用了我這種方法後,不用分表也可以完美解決!
答案就是:複合索引!有一次設計mysql索引的時候,無意中發現索引名字可以任取,可以選擇幾個字段進來,這有什麼用呢?開始的select id from collect order by id limit 90000,10; 這麼快就是因為走了索引,可是如果加了where 就不走索引了。抱着試試看的想法加了 search(vtype,id) 這樣的索引。然後測試
select id from collect where vtype=1 limit 90000,10; 非常快!0.04秒完成!
再測試: select id ,title from collect where vtype=1 limit 90000,10; 非常遺憾,8-9秒,沒走search索引!
再測試:search(id,vtype),還是select id 這個語句,也非常遺憾,0.5秒。
綜上:如果對於有where 條件,又想走索引用limit的,必須設計一個索引,將where 放第一位,limit用到的主鍵放第2位,而且只能select 主鍵!
完美解決了分頁問題了。可以快速返回id就有希望優化limit , 按這樣的邏輯,百萬級的limit 應該在0.0x秒就可以分完。看來mysql 語句的優化和索引時非常重要的!
好了,回到原題,如何將上面的研究成功快速應用於開發呢?如果用複合查詢,我的輕量級框架就沒的用了。分頁字符串還得自己寫,那多麻煩?這裡再看一個例子,思路就出來了:
select * from collect where id in (9000,12,50,7000); 竟然 0秒就可以查完!
mygod ,mysql 的索引竟然對於in語句同樣有效!看來網上說in無法用索引是錯誤的!
有了這個結論,就可以很簡單的應用於輕量級框架了:
代碼如下:
$db=dblink();
$db-pagesize=20;
$sql=”select id from collect where vtype=$vtype”;
$db-execute($sql);
$strpage=$db-strpage(); //將分頁字符串保存在臨時變量,方便輸出
while($rs=$db-fetch_array()){
$strid.=$rs[‘id’].’,’;
}
$strid=substr($strid,0,strlen($strid)-1); //構造出id字符串
$db-pagesize=0; //很關鍵,在不註銷類的情況下,將分頁清空,這樣只需要用一次數據庫連接,不需要再開;
$db-execute(“select id,title,url,sTime,gTime,vtype,tag from collect where id in ($strid)”);
php while($rs=$db-fetch_array()):
tr
td$amp;amp;$amp;nbsp; php echo $rs[‘id’]; $amp;amp;$lt;/td
td$amp;amp;$amp;nbsp; php echo $rs[‘url’]; $amp;amp;$lt;/td
td$amp;amp;$amp;nbsp; php echo $rs[‘sTime’]; $amp;amp;$lt;/td
td$amp;amp;$amp;nbsp; php echo $rs[‘gTime’]; $amp;amp;$lt;/td
td$amp;amp;$amp;nbsp; php echo $rs[‘vtype’]; $amp;amp;$lt;/td
td$amp;amp;$amp;nbsp;a act=showid= php echo $rs[‘id’]; $amp;quot;$ target=”_blank”$amp;amp;$lt; php echo $rs[‘title’]; $amp;amp;$lt;/a$amp;amp;$lt;/td
td$amp;amp;$amp;nbsp; php echo $rs[‘tag’]; $amp;amp;$lt;/td
/tr
php endwhile;
/table
php
echo $strpage;
通過簡單的變換,其實思路很簡單:1)通過優化索引,找出id,並拼成 “123,90000,12000” 這樣的字符串。2)第2次查詢找出結果。
小小的索引+一點點的改動就使mysql 可以支持百萬甚至千萬級的高效分頁!
通過這裡的例子,我反思了一點:對於大型系統,PHP千萬不能用框架,尤其是那種連sql語句都看不到的框架!因為開始對於我的輕量級框架都差點崩潰!只適合小型應用的快速開發,對於ERP,OA,大型網站,數據層包括邏輯層的東西都不能用框架。如果程序員失去了對sql語句的把控,那項目的風險將會成幾何級數增加!尤其是用mysql 的時候,mysql 一定需要專業的dba 才可以發揮他的最佳性能。一個索引所造成的性能差別可能是上千倍!
PS: 經過實際測試,到了100萬的數據,160萬數據,15G表,190M索引,就算走索引,limit都得0.49秒。所以分頁最好別讓別人看到10萬條以後的數據,要不然會很慢!就算用索引。經過這樣的優化,mysql到了百萬級分頁是個極限!但有這樣的成績已經很不錯,如果你是用sqlserver肯定卡死!而 160萬的數據用 id in (str) 很快,基本還是0秒。如果這樣,千萬級的數據,mysql應該也很容易應付。
怎樣用PHP逐行讀取數G的大文件最有效率且不會搞爆內存
你需要安裝php運行環境,才能解析php文件!百度phpstudy!一鍵安裝,然後把php放在phpstudy的網站目錄!然後就可以用sublime編寫!然後測試! 要直接sublime+瀏覽器只可以運行html+script! 歡迎拍磚
最高哪個php版本支持iis6
PHP5.3x+IIS6完全配置方法,PHP5.3以上版本全新配置IIS方法 FastCGI方式(一…
在IIS6.0下安裝Fastcgi+PHP來運行PHP程序(未裝alpha),終於實現手工配置 IIS 6 下以 FastCGI 跑 PHP
PS:微軟提升PHP在IIS下的性能 FastCGI Extension for IIS6.0% ~ d# L0 v T1 o D( U; ^; j
微軟已經和PHP社區共同努力了一年之久,他們終於研發出 能讓IIS更快地解析PHP的方法,用戶們甚至不需要做基準測試就可以明顯感覺到PHP解析速度加快.早在2006年,微軟就和Zend等廠商一起研發 Windows Server下的優化工作,IIS產品組已經公布了IIS6和7的FastCGI擴展,它能讓PHP執行效率更高. PHP一直以來是IIS的尷尬,用PHP擴展的速度跟不上其它服務端(甚至還有一些致命問題例如在某內存地址報錯),而PHP又比ASP.net普及得 多,因此微軟需要在IIS+PHP上突破市場. 微軟去年底發佈了ii6的fastcgi模塊,可以免費下載,使用IIS6的您不妨在您的測試環境上試一下,沒準會有驚喜哦! 今天將服務器上的php支持改成了fastcgi,目前運行穩定.fastcgi的iis模塊可以讓流行的應用框架在iis上支持fastcgi協議以提 供高性能和可用性的訪問服務,fastcgi面向現有的網絡服務器提供高性能的cgi替代標準。具體php安裝方法我記錄下來,其中包括出現的錯誤.
1.下載 FastCGI For IIS6 5 A( c* Z’ E” t1 {. t, X
fcgisetup32.msi(FastCGI Extension for IIS 6.0 x86)- B: u, q, t’ H” K: S4 t# J
下載:http//,選擇: x86. ?8 ~ A7 t7 i
# ? i2 s’ U f% K
或者直接下載:http//go.microsoft.com/?linkid=96556962 v$ { j7 X8 O ~
下載之後,雙擊運行進行安裝。
(FakeCGI調試工具(備用):下載fake.zip http//blogs.iis.net/rickjames/attachment/1563148.ashx )
‘ @” ^! W# d’ F. @# c5 [
安裝後在 C:WINDOWSsystem32inetsrv 目錄下產生了五個文件。如下圖: B; a5 ]* v8 i% Z% b8 j2 q
同時在 IIS 的 「Web 服務擴展」里多了 FastCGI Handler。2 p3 o- h+ q, M/ d7 q
9 A- R; U( Q5 j8 `% W0 K* x- J. {
下載安裝VC9運行庫 即VISUAL C++ 2008
Microsoft Visual C++ 2008 Redistributable Package (x86)下載地址:
點擊這裡下載
2.下載 PHP5.3.0 Windows 版
由於PHP5.3的全新特效及改進,原有的isapi方式解析PHP腳本已經不被支持,PHP從5.3.0以後的版本開始使用微軟的fastcgi模式,這是一個更先進的方式,運行速度更快,更穩定!
新版本的PHP5.3通過以往老方法已經不能在IIS上安裝了,下載IIS下的PHP,下載地址http//windows.php.net/download/,(注意IIS下要選擇VC9的版本)解壓到所需目錄,該目錄需要給予
一、如何選擇PHP5.3的VC9版本和VC6版本
VC6版本是使用Visual Studio 6編譯器編譯的,如果你的PHP是用Apache來架設的,那你就選擇VC6版本。
VC9版本是使用Visual Studio 2008編譯器編譯的,如果你的PHP是用IIS來架設的,那你就選擇VC9版本。
二、如何選擇PHP5.3的Thread Safe和Non Thread Safe版本
先從字面意思上理解,Thread Safe是線程安全,執行時會進行線程(Thread)安全檢查,以防止有新要求就啟動新線程的CGI執行方式而耗盡系統資源。Non Thread Safe是非線程安全,在執行時不進行線程(Thread)安全檢查。
再來看PHP的兩種執行方式:ISAPI和FastCGI。
ISAPI執行方式是以DLL動態庫的形式使用,可以在被用戶請求後執行,在處理完一個用戶請求後不會馬上消失,所以需要進行線程安全檢查,這樣來提高程序的執行效率,所以如果是以ISAPI來執行PHP,建議選擇Thread Safe版本;
而FastCGI執行方式是以單一線程來執行操作,所以不需要進行線程的安全檢查,除去線程安全檢查的防護反而可以提高執行效率,所以,如果是以FastCGI來執行PHP,建議選擇Non Thread Safe版本。
user讀取運行權限,
選擇:PHP 5.3 (5.3.0)’ Z* Z0 r% I) ~! F* r4 f+ V. R’ b
VC9 x86 Thread Safe (2009-Jun-30 08:52:56) Zip [13.54MB]
sha1: f049c806744855e4420844d47e051949fcf06661
下載 .zip 格式的版本,解壓縮下載的 php-5.3.0-Win32-VC9-x86.zip 文件,並將其複製到:X:Server_Corephp目錄(你可以根據自己的意願解壓到別的目錄。),並給 IIS 啟動帳戶組或用戶賦予讀取和運行權限。如下圖:
+ A( b2 ^’ Y6 K7 N9 ^8 _
: I” N9 {8 q: R* E’ h9 j2 D
3. 註冊 PHP 到 FastCGI % U3 L0 {. m1 @+ @# [
打開 C:WINDOWSsystem32inetsrvfcgiext.ini 文件。
; This is the configuration file for the FastCGI handler for IIS 6.0.: O: q. R4 u+ n9 f
; The FastCGI handler will look for this file in the same directory as
; fcgiext.dll. By default, the FastCGI installer will place this file into
; the %windir%system32inetsrv directory.
– E( a5 J3 l’ R% H8 n
我個人的理解是,只要「Web 服務擴展」里的 FastCGI Handler 為允許時,在加載 fcgiext.dll 時,會讀取 fcgiext.ini 配置文件的內容,根據裏面的配置為每個網站提供映射。
在 [Types] 下添加以下配置: ; `9 c; v2 t9 b6 W- `; y’ r9 H6 H7 S
[Types]/ K. X# n9 p4 I9 e
8 b, @+ K$ f6 }; c4 w
php=PHP
[PHP]
ExePath=X:Server_CorePHPphp-cgi.exe
這裡要用:「」不能用「/」,「php」表示擴展名,「PHP」是配置節名稱,以「[PHP]」定義。 (選你自己的安裝的目錄,下同。)
) U. P; P N: w0 |7 D’ u” f h- e( c8 R
4. 配置 php.ini
將 X:Server_CorePHPphp.ini-production 複製一個,然後重命名為 X:Server_CorePHPphp.ini ! q4 H: N9 X) K. X9 e }( S
找到PHP安裝目錄下的php.ini-production並改名為php.ini文件,找到下面% n4 k. G8 ?4 N# K! P. B
[Date]7 R _* z$ ?% u’ ? t’ v
; Defines the default timezone used by the date functions
; http//php.net/date.timezone
; date.timezone =, E+ d8 |! L0 J; N
更改為並去除前面的「;」:
[Date]( c% H4 u” v2 ~4 h( R4 @4 K
; Defines the default timezone used by the date functions
; http//php.net/date.timezone
date.timezone = Asia/Shanghai Q, @2 J ^9 t s) Q0 J
如果不改以上的date.timezone可能打開網頁會提示500錯誤
找到6 s- j% ?# x$ F, h
; On windows:
; extension_dir = “ext”
改為. R- g. Z+ ~8 ” D: O9 g
; On windows:
extension_dir = “X:Server_CorePHPext”
9 V2 g8 k’ a- V9 ” T” u/ z
找到:fastcgi.impersonate = 1;這句,把前面的;去掉, fastcgi.impersonate = 1
如下圖:
5 P5 K9 c- [ n0 J( D( n
找到:short_open_tag= Off;改為
short_open_tag= On3 n2 X2 Y3 c( v) a# y6 X0 g+ {# ]
8 F0 L5 ]7 h8 w6 z. w
至於php.ini裏面的extension開啟方式,根據自己所需,找到:Windows Extensions 在 Windows Extensions 下方的動態模塊配置中,需要打開以下模塊支持:(去掉模塊配置每行前面的;號即可)比如我的是: 7 v; k* P1 c
;extension=php_bz2.dll: n+ O” R$ Z) _7 [* B( c( D. K
;extension=php_curl.dll
;extension=php_dba.dll’ f6 Y* p3 T4 R% q- c4 ] Z7 G
extension=php_mbstring.dll” C* _: V3 z- F% m
extension=php_exif.dll7 l4 N2 N” e {
;extension=php_fileinfo.dll7 E( X0 ~7 r; C* F9 j
extension=php_gd2.dll5 x9 ^1 g8 Q5 S” B F
;extension=php_gettext.dll$ O’ S. v1 i2 O$ q. H: O; G
;extension=php_gmp.dll
;extension=php_intl.dll
;extension=php_imap.dll
;extension=php_interbase.dll. a! M+ _) z: _ P* @
extension=php_ldap.dll
;extension=php_ming.dll
;extension=php_mssql.dll3 g0 O) n8 c6 }9 M9 T7 X
extension=php_mysql.dll
extension=php_mysqli.dll
;extension=php_oci8.dll ; Use with Oracle 10gR2 Instant Client
;extension=php_oci8_11g.dll ; Use with Oracle 11g Instant Client
;extension=php_openssl.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_mssql.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll. K0 q3 p6 t, ^# K) i* K
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll. { w3 O# E$ , U7 j% y$ r1 I
;extension=php_pdo_sqlite.dll
;extension=php_pgsql.dll$ T- g9 D 7 D3 Z+ n# S% U M
;extension=php_phar.dll
;extension=php_pspell.dll
;extension=php_shmop.dll
;extension=php_snmp.dll. K9 m+ o) O9 @7 W @0 N
;extension=php_soap.dll p S8 Q’ s+ I, F0 L5 a1 v
;extension=php_sockets.dll
;extension=php_sqlite.dll
;extension=php_sqlite3.dll0 H5 ^$ l0 V7 g, M
;extension=php_sybase_ct.dll
;extension=php_tidy.dll2 m’ J5 Q; A- T9 n
;extension=php_xmlrpc.dll
;extension=php_xsl.dll% h* t/ J” J) a8 t7 Q( I’ n5 R9 F$ q
;extension=php_zip.dll
注意最後一個php_zip.dll這個在我下載下來的php5.3.0的ext內是不存在的,所以如果開啟會報錯誤,如果實在需要這個DLL,可以從PHP5.2中拷貝過去(我的不行)
保存 php.ini 文件,並將其複製到 C:Windows ,並刪除 X:Server_CorePHPphp.ini,不刪除有時IIS報500錯!
4 B0 M. ]9 U E3 d1 V
5. 配置網站 q% W* / n) c’ `- Y
; t4 X! x( V, T! [) [2 |4 [
打開IIS管理器,網站上點右鍵-屬性-主目錄-配置-添加,配置如下圖” j9 W, {” c4 S% @2 I1 x
Q6 _: a8 g, m q/ R, R
# ^% v* ?# G6 |
可執行文件路徑:C:WINDOWSsystem32inetsrvfcgiext.dll
6.相關權限配置
C:WINDOWSsystem32inetsrvfcgiext.dll 的權限,NETWORK_SERVICE和IUSR_***(Internet來賓賬戶)的可讀和運行權限。
PHP安裝目錄的權限,NETWORK_SERVICE的讀和運行權限
網站所在目錄的權限,IUSR_***(Internet來賓賬戶)的讀取和運行權,需要寫入的目錄單獨再給寫入權
7. 寫個 php 測試下吧
” m: |: h# L’ b% y; }
修改完在IIS上或者命令提示符運行iisreset命令重啟IIS服務,這步很重要!
( M6 w6 {! R y ~4 F
測試是否安裝成功!
建立一個網站,phpinfo.php文件內容為:/ o+ p’ n$ t8 T+ O( b2 s P. P
文件:phpinfo.php
?php
phpinfo();
?
6 j- O: M6 | [, p/ p t
看到類似以下效果說明你的服務器可以跑 php 了。
php 視頻教程下載
鏈接:
提取碼: c9fj
《PHP自學視頻教程》 分3篇共22章,其中,第1篇為入門篇,主要包括了解PHP、PHP開發環境搭建、PHP開發基礎、PHP流程控制語句、函數、字符串操作、正則表達式、PHP數組、PHP與Web頁面交互、日期和時間等內容;第2篇為提高篇,主要包括MySQL數據庫設計、PHP操作MySQL數據庫、Cookie和Session、圖形圖像處理技術、文件和目錄處理技術、面向對象、PDO數據庫抽象層、程序調試與錯誤處理、Ajax技術、Smarty模板技術等內容;第3篇為實戰篇,主要包括明日企業網、應用Smarty模板開發電子商務平台等兩個實戰項目。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/293266.html