我在mysql最佳化的時候,隨便建立了一張暫存資料表,產生200W條資料,但是不明白,產生的記錄中有重複的,而且還比較多,不解
在此謝謝諸位了
$conn=new mysqli("localhost","root","","test");$conn->query("set names utf8");function str_rand($num){ $str="abcdefghijkmnpqrstuvwxyz0123456789"; $return_str=""; for($i=0;$i<$num;$i++){ $return_str.=substr($str,rand(0,33),1); } return $return_str;}$sql="insert into news (id,title,author,keywords,descrition) values (?,?,?,?,?)";$mysqli_stmt=$conn->prepare($sql);for($i=1;$i<=2000000;$i++){ $title=str_rand(rand(3,30)); $author=str_rand(rand(3,20)); $keywords=str_rand(rand(10,100)); $descrition=str_rand(rand(30,255)); $mysqli_stmt->bind_param("issss",$i,$title,$author,$keywords,$descrition); $res=$mysqli_stmt->execute();}$mysqli_stmt->close();$conn->close();
備忘:執行時間過長,肯定超過了php的最大執行時間,修改了設定檔,插入的資料中,100條以後的記錄中,比如查詢title='xxx'的欄位,能查詢出1.4W多條
回複內容:
我在mysql最佳化的時候,隨便建立了一張暫存資料表,產生200W條資料,但是不明白,產生的記錄中有重複的,而且還比較多,不解
在此謝謝諸位了
$conn=new mysqli("localhost","root","","test");$conn->query("set names utf8");function str_rand($num){ $str="abcdefghijkmnpqrstuvwxyz0123456789"; $return_str=""; for($i=0;$i<$num;$i++){ $return_str.=substr($str,rand(0,33),1); } return $return_str;}$sql="insert into news (id,title,author,keywords,descrition) values (?,?,?,?,?)";$mysqli_stmt=$conn->prepare($sql);for($i=1;$i<=2000000;$i++){ $title=str_rand(rand(3,30)); $author=str_rand(rand(3,20)); $keywords=str_rand(rand(10,100)); $descrition=str_rand(rand(30,255)); $mysqli_stmt->bind_param("issss",$i,$title,$author,$keywords,$descrition); $res=$mysqli_stmt->execute();}$mysqli_stmt->close();$conn->close();
備忘:執行時間過長,肯定超過了php的最大執行時間,修改了設定檔,插入的資料中,100條以後的記錄中,比如查詢title='xxx'的欄位,能查詢出1.4W多條
PHP
的rand()
採用的是偽隨機演算法,其產生的資料是有規律的。
給你一張真隨機產生的資料分布圖和一張PHP rand()
產生的資料分布圖,結果一目瞭然。
真隨機:結果均勻分布
PHP rand()
:有明顯條紋(規律性)
而用mt_rand()就不存在這樣的問題
php7的random_int()會比mt_rand()再好一些
如果需要產生無重複的隨機數列,一般是預先產生一個連續的數列,存到一個list裡面。然後通過偽隨機演算法擷取index,取出數值;或者寫一個洗牌方法打亂該連續數列,通過偽隨機演算法控制洗牌,然後順序讀取。
當然,偽隨機演算法最重要的還是種子的選擇。種子的來源最常用的當然是目前時間戳。也可以有其他的方式,這些網上很多關於隨機數種子的文章,可以去看看。
引用PHP手冊中對mt_rand()函數的介紹:
很多老的 libc 的隨機數發生器具有一些不確定和未知的特性而且很慢。PHP 的 rand() 函數預設使用 libc 隨機數發生器。mt_rand() 函數是非正式用來替換它的。該函數用了 » Mersenne Twister 中已知的特性作為隨機數發生器,它可以產生隨機數值的平均速度比 libc 提供的 rand() 快四倍。
你需要把rand()換成mt_rand(),另外可以使用GUID來產生唯一資料。