我有一個腳本,用於查詢50,000條記錄的數據庫,並嘗試創建一個表,概述每星期每週向數據庫中添加新條目的每週報告。使用php優化多周mysql查詢
我有一個約束:報告必須從$START_DATE
開始,這是網站每個部分下數據庫中任何用戶的第一天存在記錄。這意味着我不能使用查找預定義日期的函數,我必須計算第一個用戶輸入數據庫的部分中的用戶,直到一個星期後,直到$END_DATE
(通常是time()
)爲止。
大約需要5秒查詢數據庫的count(*)
或select *
:
mysql> select count(*), user_type from users_table where user_permissions = "normal" group by user_type;
+----------+-----------------+
| count(*) | user_type |
+----------+-----------------+
| 2210 | myspace_user |
| 48659 | facebook_user |
+----------+-----------------+
2 rows in set (4.73 sec)
我有,通過雲和查詢數據庫中的一堆每user_type
次一些PHP代碼來獲得的詳表每週報告。問題是,有12個星期和兩個用戶類型,因此整個過程最多需要兩分鐘。網站的某些部分有兩種以上的用戶類型,這些查詢需要更長的時間。下面的代碼:
$start = strtotime($START_DATE);
$end = strtotime($END_DATE);
for ($i = 0; $start+$i < time() && $start+$i < $end; $i+= (7*24*60*60)) {
$weekly_total = 0;
foreach($USERTYPES as $usertype) {
$q = "select count(*) from users_table where user_type = '" . $usertype . "' and user_permissions = 'normal'";
$q .= " and UNIX_TIMESTAMP(timestmp) >= " . strval($start+$i) . " and UNIX_TIMESTAMP(timestmp) <= " . strval($start+$i+(7*24*60*60));
$r = mysql_query($q);
$v = mysql_fetch_array($r);
$table['weekly'][gmdate("Y-m-d", $start+$i)][$usertype] += $v[0];
$weekly_total += $v[0];
}
$table['weekly'][gmdate("Y-m-d", $start+$i)]['weekly_total'] = $weekly_total;
}
最後我有12個條目,像這樣的僞代碼結束的陣列,具有基本結構:
// ...previous entries
$table['weekly']['2013-07-01'] = array(
'myspace_user' => 123,
'facebook_user' => 1234,
'weekly_total' => 1357
);
$table['weekly']['2013-07-08'] = array(
// ...and so on
,其產生這些查詢,並將它們保存到該表的過程需要很長時間。有什麼辦法可以使MySQL或PHP函數更高效,所以我不必爲每週生成一個單獨的查詢?
這些SELECT查詢中的每一個需要4.75秒,與我的完全相同。計算兩種類型12周的整個過程仍需要2分鐘。從int到字符串的date-> timestamp轉換花費的時間可以忽略不計,並且用於顯示目的(也因爲我無法控制某些數據如何到達我家門口)。 – Joey
你也可以通過只有最低/最高可能的日期範圍,並提取一個派生字段,例如'WEEK(timestmp)',以便確定記錄應該處於哪個時期,從而將其減少爲單個查詢。 –
@joey :如果SELECT本身需要4.75秒,那麼表的結構可能有問題......有多少條記錄? 'user_type'編入索引了嗎?也許'user_permissions'是一個字符串?在這裏做出錯誤的選擇會影響你的查詢。 – JvO