我已經分配了一些任務,爲一個網站創建一些圖形統計數據,並保存了一些數據。php mysql優化
Facts: - 有3個數據庫在使用。 dbCurrent,dbStats,dbBackup。 dbCurrent是網站的主要數據庫 dbStats包含各種統計和跟蹤數據表 dbBackup包含過去五年的統計/跟蹤表。
- 我將使用來自兩個數據庫中的數據(dbStats,DBBACKUP)
- 表名是:stats2006,stats2007,stats2008等,除了目前的統計這僅僅是 「統計」。每個表格都有其年份的數據。
- 每年數據的表結構是相同的: primaryID字段是整數 產品id字段是整數 dateMonitor字段是整數(unixtimestamp) 頁面名字段爲varchar(20)
- 的productID,dateMonitor,頁面名字段也有索引
換句話說,什麼產品在什麼日期和什麼頁面被查看。
所以,我認爲是創建一個循環出每個表並獲取我的數據。 我的每一個查詢看起來像:
Select COUNT(primaryID) as myCounter FROM $tablename WHERE $conditions
其中$表名和$條件是基於每一個循環變量。 所有條件類似於:
- 和DATE1之間dateMonitor DATE2
- 頁面名= '一些VAL'
- 的productID IN($ comma_separated_values)上述
所有
當我嘗試在'y'年(從admin/moderator動態選擇)中創建比較'x'產品的報表時,腳本運行超過15分鐘。
我正在尋找一種方法來改善腳本的性能。 邏輯/結構我使用至今,如下:
Loop through products to find the ids to use (typical format is: x,y,z (comma separated values)
Open Loop through years/months
Execute one sql query for each affected table/database to get the number of affected rows.
Close year loop
Send data to graph script (jquery jqPlot to be exact) to print on screen
任何幫助/想法理解。
編輯: 基於@Narf建議與UNION ALL,我構建了一個基於12個子選擇語句1個單查詢:
SELECT COUNT(*) AS monthlyTotal FROM db1.table1 WHERE dateMonitor>='1167606001' AND dateMonitor<='1170284399' AND dateMonitor='test'
UNION ALL
SELECT COUNT(*) AS monthlyTotal FROM db1.table2 WHERE dateMonitor>='1170284401' AND dateMonitor<='1172703599' AND dateMonitor='test' ...
每個SELECT語句是指單月時間。演示代碼:
for ($m=1; $m<=12; $m++)
{
$startDate = mktime(0, 0, 1, $m, 1, $myYear);
$daysOfMonth = date("t", mktime(10, 10, 10, $m, 10, $myYear));
$endDate = mktime(23, 59, 59, $m, $daysOfMonth, $myYear);
$query_chk1 .= "SELECT COUNT(*) AS monthlyTotal FROM db1.table1 WHERE dateMonitor>='$startDate' AND dateMonitor<='$endDate' AND pageName='test' UNION ALL ";
}
$query_chk1 = substr($query_chk1, 0, -10);
EDIT2:創建組合索引(由@ypercube所建議的)後,我看到在執行時間一些輕微的下降時間。
現在我有11分鐘的平均執行時間(原來的時間爲15-17分鐘)
這幫助了很多以減少執行時間。
謝謝。
你有什麼指標在桌子上? –
另外還有一個提示:與COUNT(字段)相比,MySQL中的COUNT(*)更快。並且給出相同的結果,只要'field'不可爲空。 –
@ypercube:productID,dateMonitor,pageName字段是每個表中的索引 – andrew