php千萬級數(shù)據(jù)如何處理,php千萬級數(shù)據(jù)怎么優(yōu)化

Thinkphp下導(dǎo)入千萬級txt文件好方法

$fp?=?fopen($file,?"r");

創(chuàng)新互聯(lián)建站致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營銷,提供成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營銷、成都小程序開發(fā)、公眾號商城、等建站開發(fā),創(chuàng)新互聯(lián)建站網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢。

$num?=?10;

$chunk?=?4096;

$fs?=?sprintf("%u",?filesize($file));

$max?=?(intval($fs)?==?PHP_INT_MAX)???PHP_INT_MAX?:?filesize($file);

for?($len?=?0;?$len??$max;?$len?+=?$chunk)?{

$seekSize?=?($max?-?$len??$chunk)???$chunk?:?$max?-?$len;

fseek($fp,?($len?+?$seekSize)?*?-1,?SEEK_END);

$readData?=?fread($fp,?$seekSize)?.?$readData;

if?(substr_count($readData,?"n")?=?$num?+?1)?{

preg_match("!(.*?n){".($num)."}$!",?$readData,?$match);

$data?=?$match[0];

break;

}

}

fclose($fp);

echo?$data;

只要不讀到內(nèi)存操作就好辦

php+mysql優(yōu)化,百萬至千萬級快速分頁mysql性能到底能有多高

php+Mysql 優(yōu)化,百萬至千萬級快速分頁

MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考這個問題還是從前天開始。有過痛苦有過絕望,到現(xiàn)在充滿信心!MySql 這個數(shù)據(jù)庫絕對是適合dba級的高手去玩的,一般做一點1萬篇新聞的小型系統(tǒng)怎么寫都可以,用xx框架可以實現(xiàn)快速開發(fā)??墒菙?shù)據(jù)量到了10萬,百萬至千萬,他的性能還能那么高嗎?一點小小的失誤,可能造成整個系統(tǒng)的改寫,甚至更本系統(tǒng)無法正常運行!好了,不那么多廢話了。用事實說話,看例子:

數(shù)據(jù)表 collect ( id, title ,info ,vtype) 就這4個字段,其中 title 用定長,info 用text, id 是逐漸,vtype是tinyint,vtype是索引。這是一個基本的新聞系統(tǒng)的簡單模型。現(xiàn)在往里面填充數(shù)據(jù),填充10萬篇新聞。

最后collect 為 10萬條記錄,數(shù)據(jù)庫表占用硬盤1.6G。OK ,看下面這條sql語句:

select id,title from collect limit 1000,10; 很快;基本上0.01秒就OK,再看下面的

select id,title from collect limit 90000,10; 從9萬條開始分頁,結(jié)果?

8-9秒完成,my god 哪出問題了????其實要優(yōu)化這條數(shù)據(jù),網(wǎng)上找得到答案??聪旅嬉粭l語句:

select id from collect order by id limit 90000,10; 很快,0.04秒就OK。為什么?因為用了id主鍵做索引當(dāng)然快。網(wǎng)上的改法是:

select id,title from collect where id=(select id from collect order by id limit 90000,1) limit 10;

這就是用了id做索引的結(jié)果??墒菃栴}復(fù)雜那么一點點,就完了??聪旅娴恼Z句

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秒的速度了。和測試結(jié)果8-9秒到了一個數(shù)量級。從這里開始有人提出了分表的思路,這個和discuz 論壇是一樣的思路。思路如下:

建一個索引表: t (id,title,vtype) 并設(shè)置成定長,然后做分頁,分頁出結(jié)果再到 collect 里面去找info 。 是否可行呢?實驗下就知道了。

10萬條記錄到 t(id,title,vtype) 里,數(shù)據(jù)表大小20M左右。用

select id from t where vtype=1 order by id limit 90000,10; 很快了?;旧?.1-0.2秒可以跑完。為什么會這樣呢?我猜想是因為collect 數(shù)據(jù)太多,所以分頁要跑很長的路。limit 完全和數(shù)據(jù)表的大小有關(guān)的。其實這樣做還是全表掃描,只是因為數(shù)據(jù)量小,只有10萬才快。OK,來個瘋狂的實驗,加到100萬條,測試性能。

加了10倍的數(shù)據(jù),馬上t表就到了200多M,而且是定長。還是剛才的查詢語句,時間是0.1-0.2秒完成!分表性能沒問題?錯!因為我們的limit還是9萬,所以快。給個大的,90萬開始

select id from t where vtype=1 order by id limit 900000,10; 看看結(jié)果,時間是1-2秒!

why   分表了時間還是這么長,非常之郁悶!有人說定長會提高limit的性能,開始我也以為,因為一條記錄的長度是固定的,mysql 應(yīng)該可以算出90萬的位置才對??? 可是我們高估了mysql 的智能,他不是商務(wù)數(shù)據(jù)庫,事實證明定長和非定長對limit影響不大?怪不得有人說 discuz到了100萬條記錄就會很慢,我相信這是真的,這個和數(shù)據(jù)庫設(shè)計有關(guān)!

難道MySQL 無法突破100萬的限制嗎???到了100萬的分頁就真的到了極限???

答案是: NO !!!! 為什么突破不了100萬是因為不會設(shè)計mysql造成的。下面介紹非分表法,來個瘋狂的測試!一張表搞定100萬記錄,并且10G 數(shù)據(jù)庫,如何快速分頁!

好了,我們的測試又回到 collect表,開始測試結(jié)論是: 30萬數(shù)據(jù),用分表法可行,超過30萬他的速度會慢道你無法忍受!當(dāng)然如果用分表+我這種方法,那是絕對完美的。但是用了我這種方法后,不用分表也可以完美解決!

答案就是:復(fù)合索引!有一次設(shè)計mysql索引的時候,無意中發(fā)現(xiàn)索引名字可以任取,可以選擇幾個字段進來,這有什么用呢?開始的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的,必須設(shè)計一個索引,將where 放第一位,limit用到的主鍵放第2位,而且只能select 主鍵!

完美解決了分頁問題了??梢钥焖俜祷豬d就有希望優(yōu)化limit , 按這樣的邏輯,百萬級的limit 應(yīng)該在0.0x秒就可以分完。看來mysql 語句的優(yōu)化和索引時非常重要的!

好了,回到原題,如何將上面的研究成功快速應(yīng)用于開發(fā)呢?如果用復(fù)合查詢,我的輕量級框架就沒的用了。分頁字符串還得自己寫,那多麻煩?這里再看一個例子,思路就出來了:

select * from collect where id in (9000,12,50,7000); 竟然 0秒就可以查完!

mygod ,mysql 的索引竟然對于in語句同樣有效!看來網(wǎng)上說in無法用索引是錯誤的!

有了這個結(jié)論,就可以很簡單的應(yīng)用于輕量級框架了:

代碼如下:

$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); //構(gòu)造出id字符串

$db-pagesize=0; //很關(guān)鍵,在不注銷類的情況下,將分頁清空,這樣只需要用一次數(shù)據(jù)庫連接,不需要再開;

$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)通過優(yōu)化索引,找出id,并拼成 "123,90000,12000" 這樣的字符串。2)第2次查詢找出結(jié)果。

小小的索引+一點點的改動就使mysql 可以支持百萬甚至千萬級的高效分頁!

通過這里的例子,我反思了一點:對于大型系統(tǒng),PHP千萬不能用框架,尤其是那種連sql語句都看不到的框架!因為開始對于我的輕量級框架都差點崩潰!只適合小型應(yīng)用的快速開發(fā),對于ERP,OA,大型網(wǎng)站,數(shù)據(jù)層包括邏輯層的東西都不能用框架。如果程序員失去了對sql語句的把控,那項目的風(fēng)險將會成幾何級數(shù)增加!尤其是用mysql 的時候,mysql 一定需要專業(yè)的dba 才可以發(fā)揮他的最佳性能。一個索引所造成的性能差別可能是上千倍!

PS: 經(jīng)過實際測試,到了100萬的數(shù)據(jù),160萬數(shù)據(jù),15G表,190M索引,就算走索引,limit都得0.49秒。所以分頁最好別讓別人看到10萬條以后的數(shù)據(jù),要不然會很慢!就算用索引。經(jīng)過這樣的優(yōu)化,mysql到了百萬級分頁是個極限!但有這樣的成績已經(jīng)很不錯,如果你是用sqlserver肯定卡死!而 160萬的數(shù)據(jù)用 id in (str) 很快,基本還是0秒。如果這樣,千萬級的數(shù)據(jù),mysql應(yīng)該也很容易應(yīng)付。

php 學(xué)習(xí)

是一個表有千萬行數(shù)據(jù)。

你可以用瘋狂復(fù)制插入數(shù)據(jù)試試,在達到十萬條時,查詢速度明顯下降。

優(yōu)化也不難。

1.行變列,例如4個字段的表有4000萬條數(shù)據(jù),你就做成400個字段,那么表的數(shù)據(jù)只有10萬條。因為這種做法和數(shù)據(jù)庫字段越少越好的原則相違背,所以很多人不敢用。但是經(jīng)我嘗試,這種做法好得不得了。

2.行變列是一種方向,如果嫌一次增加字段過多,那就做多幾張表,每張表的字段適中,大概40來個,每張表幾萬條記錄。

總之一句話,數(shù)據(jù)庫設(shè)計一個原則,字段越少越好,表越少越好,行越少越好,列越少越好。

這四個少相互矛盾。

這些原則是由數(shù)據(jù)庫的功能決定的,數(shù)據(jù)庫的兩個基本功能,存和取。

存在一個表方便,是以取的艱難為代價的。

如果存肯艱難點,那么取就輕松了。

什么數(shù)據(jù)庫設(shè)計原則還有什么范式逆范式索引反索引等等xxx原則不過是這對基本矛盾的產(chǎn)物而已。

自己贊一個。

php千萬級處理是什么?

數(shù)據(jù)庫方面:添加索引,分表或者分區(qū),優(yōu)化sql語句

程序方面:使用緩存,生成靜態(tài),優(yōu)化php語句

服務(wù)器方面:增加服務(wù)器配置,或者增加服務(wù)器的數(shù)量

其他方面:圖片獨立出去,最好是做異步加載,壓縮js,css文件

php+mysql 如何優(yōu)化千萬級數(shù)據(jù)模糊查詢加快

關(guān)于mysql處理百萬級以上的數(shù)據(jù)時如何提高其查詢速度的方法

最近一段時間由于工作需要,開始關(guān)注針對Mysql數(shù)據(jù)庫的select查詢語句的相關(guān)優(yōu)化方法。

由于在參與的實際項目中發(fā)現(xiàn)當(dāng)mysql表的數(shù)據(jù)量達到百萬級時,普通SQL查詢效率呈直線下降,而且如果where中的查詢條件較多時,其查詢速度簡直無法容忍。曾經(jīng)測試對一個包含400多萬條記錄(有索引)的表執(zhí)行一條條件查詢,其查詢時間竟然高達40幾秒,相信這么高的查詢延時,任何用戶都會抓狂。因此如何提高sql語句查詢效率,顯得十分重要。以下是網(wǎng)上流傳比較廣泛的30種SQL查詢語句優(yōu)化方法:

1、應(yīng)盡量避免在 where 子句中使用!=或操作符,否則將引擎放棄使用索引而進行全表掃描。

2、對查詢進行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。

3、應(yīng)盡量避免在 where 子句中對字段進行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進行全表掃描,如:

select id from t where num is null

可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值,然后這樣查詢:

select id from t where num=0

4、盡量避免在 where 子句中使用 or 來連接條件,否則將導(dǎo)致引擎放棄使用索引而進行全表掃描,如:

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、下面的查詢也將導(dǎo)致全表掃描:(不能前置百分號)

select id from t where name like ‘%c%’

若要提高效率,可以考慮全文檢索。

6、in 和 not in 也要慎用,否則會導(dǎo)致全表掃描,如:

select id from t where num in(1,2,3)

對于連續(xù)的數(shù)值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3

7、如果在 where 子句中使用參數(shù),也會導(dǎo)致全表掃描。因為SQL只有在運行時才會解析局部變量,但優(yōu)化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然 而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:

select id from t where num=@num

可以改為強制查詢使用索引:

select id from t with(index(索引名)) where num=@num

8、應(yīng)盡量避免在 where 子句中對字段進行表達式操作,這將導(dǎo)致引擎放棄使用索引而進行全表掃描。如:

select id from t where num/2=100

應(yīng)改為:

select id from t where num=100*2

9、應(yīng)盡量避免在where子句中對字段進行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進行全表掃描。如:

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

應(yīng)改為:

select id from t where name like ‘a(chǎn)bc%’

select id from t where createdate=’2005-11-30′ and createdate’2005-12-1′

10、不要在 where 子句中的“=”左邊進行函數(shù)、算術(shù)運算或其他表達式運算,否則系統(tǒng)將可能無法正確使用索引。

11、在使用索引字段作為條件時,如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使 用,并且應(yīng)盡可能的讓字段順序與索引順序相一致。

12、不要寫一些沒有意義的查詢,如需要生成一個空表結(jié)構(gòu):

select col1,col2 into #t from t where 1=0

這類代碼不會返回任何結(jié)果集,但是會消耗系統(tǒng)資源的,應(yīng)改成這樣:

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是根據(jù)表中數(shù)據(jù)來進行查詢優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時,SQL查詢可能不會去利用索引,如一表中有字段 sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。

15、索引并不是越多越好,索引固然可以提高相應(yīng)的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數(shù)最好不要超過6個,若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有 必要。

16.應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列,因為 clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序,一旦該列值改變將導(dǎo)致整個表記錄的順序的調(diào)整,會耗費相當(dāng)大的資源。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應(yīng)將該索引建為 clustered 索引。

17、盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接時會 逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。

18、盡可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長字段存儲空間小,可以節(jié)省存儲空間,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。

19、任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。

20、盡量使用表變量來代替臨時表。如果表變量包含大量數(shù)據(jù),請注意索引非常有限(只有主鍵索引)。

21、避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。

22、臨時表并不是不可使用,適當(dāng)?shù)厥褂盟鼈兛梢允鼓承├谈行?,例如,?dāng)需要重復(fù)引用大型表或常用表中的某個數(shù)據(jù)集時。但是,對于一次性事件,最好使 用導(dǎo)出表。

23、在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應(yīng)先create table,然后insert。

24、如果使用到了臨時表,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除,先 truncate table ,然后 drop table ,這樣可以避免系統(tǒng)表的較長時間鎖定。

25、盡量避免使用游標(biāo),因為游標(biāo)的效率較差,如果游標(biāo)操作的數(shù)據(jù)超過1萬行,那么就應(yīng)該考慮改寫。

26、使用基于游標(biāo)的方法或臨時表方法之前,應(yīng)先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。

27、與臨時表一樣,游標(biāo)并不是不可使用。對小型數(shù)據(jù)集使用 FAST_FORWARD 游標(biāo)通常要優(yōu)于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數(shù)據(jù)時。在結(jié)果集中包括“合計”的例程通常要比使用游標(biāo)執(zhí)行的速度快。如果開發(fā)時 間允許,基于游標(biāo)的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。

28、在所有的存儲過程和觸發(fā)器的開始處設(shè)置 SET NOCOUNT ON ,在結(jié)束時設(shè)置 SET NOCOUNT OFF 。無需在執(zhí)行存儲過程和觸發(fā)器的每個語句后向客戶端發(fā)送 DONE_IN_PROC 消息。

29、盡量避免向客戶端返回大數(shù)據(jù)量,若數(shù)據(jù)量過大,應(yīng)該考慮相應(yīng)需求是否合理。

30、盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力。

php千萬條數(shù)據(jù)量查詢速度問題

優(yōu)化查詢,必要的索引是肯定需要的,還有就是可以考慮用臨時表實現(xiàn)

網(wǎng)頁標(biāo)題:php千萬級數(shù)據(jù)如何處理,php千萬級數(shù)據(jù)怎么優(yōu)化
當(dāng)前URL:http://muchs.cn/article40/hcipeo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、品牌網(wǎng)站設(shè)計、網(wǎng)站設(shè)計公司、網(wǎng)頁設(shè)計公司外貿(mào)建站、網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)