2014-01-17 36 views
1

我一直在更新php腳本以使用.mdb Access 2010數據庫,並且我一直在發現odbc_exec命令需要很長時間才能執行。我正在運行的SQL查詢是:odbc_exec花了很長時間來執行一個簡單的查詢

SELECT MIN(ID) AS fd FROM myTable WHERE ID > 3572 AND ([field2] LIKE '%TEXT%') 
SELECT MAX(ID) AS fd FROM myTable WHERE ID < 3572 AND ([field2] LIKE '%TEXT%') 
SELECT COUNT(*) AS fd FROM myTable WHERE ID <= 3572 AND ([field2] LIKE '%TEXT%') 
SELECT COUNT(*) AS fd FROM myTable WHERE ([field2] LIKE '%TEXT%') 

它們用於我正在更新的搜索結果分頁系統。 我的PHP代碼是這樣的:

$sql = "SELECT MIN(ID) AS fd FROM myTable WHERE ID > 3572 AND ([field2] LIKE '%TEXT%')" 

$sqlconn = odbc_connect("my_data_source","","",SQL_CURSOR_FORWARD_ONLY); 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
// more code using $data 

當我運行我的代碼,我覺得這需要幾分鐘的時間來運行,這是太長了。通過評論它後面的所有內容,我已追查到$result = odbc_exec($sqlconn, $sql);線路的罪魁禍首。我對PHP和odbc連接還不熟悉,到目前爲止我還沒有找到爲什麼需要這麼長時間的原因。直接在數據庫上運行查詢幾乎是即時的。

myTable是數據庫中的一個單表,它有大約60,000條記錄和25列數據。它沒有主鍵字段或我知道的任何索引,但添加主鍵似乎不會影響運行時間的任何顯着數量。

我已經嘗試過的一些事情包括將ODBC數據源緩衝區大小從2048增加到4096,在數據庫的ID字段中添加主鍵,並使用SQL_CUR_USE_ODBC光標選項而不是SQL_CURSOR_FORWARD_ONLY選項。

更新 我不知道這是否相關,但我注意到一些奇怪的事情,當查詢從php文件運行。 .mdb數據庫與其他幾個.mdb數據庫位於一個文件夾中,當查詢運行時,它們中的每一個都被鎖定(具有伴隨的.ldb文件)。它也導致Apache運行速度非常緩慢。

我不知道要發佈什麼其他相關信息,所以如果有什麼我失蹤請讓我知道。

+1

像'%...'可能會很慢,因爲它不會使用索引。 – Fionnuala

+0

執行PHP腳本的計算機的本地驅動器上是否爲.mdb文件? –

+0

@GordThompson是的,這是所有正在我的本地機器上運行。 – jaredk

回答

0

顯然LIKE '%TEXT%'條件是瓶頸,強制每個查詢的表掃描。如果這些LIKE條件對於每個批次的四個查詢總是相同的(即爲相同記錄子集獲得四個值),那麼使用臨時表將會有很大幫助。

爲60,000記錄的測試表,下面的代碼需要大約10秒或11秒對我最古老和creakiest測試箱運行:

$sql = "SELECT MIN(ID) AS fd FROM myTable WHERE ID > 3572 AND ([field2] LIKE '%TEXT%')"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v1 = $data['fd']; 

$sql = "SELECT MAX(ID) AS fd FROM myTable WHERE ID < 3572 AND ([field2] LIKE '%TEXT%')"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v2 = $data['fd']; 

$sql = "SELECT COUNT(*) AS fd FROM myTable WHERE ID <= 3572 AND ([field2] LIKE '%TEXT%')"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v3 = $data['fd']; 

$sql = "SELECT COUNT(*) AS fd FROM myTable WHERE ([field2] LIKE '%TEXT%')"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v4 = $data['fd']; 

但是,下面的代碼在短短的1或2秒完成在同一臺機器上:

$tempTableName = uniqid(); 

$sql = "CREATE TABLE $tempTableName (ID INTEGER PRIMARY KEY)"; 
$result = odbc_exec($sqlconn, $sql); 
$sql = 
     "INSERT INTO $tempTableName (ID) " . 
     "SELECT ID FROM myTable WHERE ([field2] LIKE '%TEXT%')"; 
$result = odbc_exec($sqlconn, $sql); 

$sql = "SELECT MIN(ID) AS fd FROM $tempTableName WHERE ID > 3572"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v1 = $data['fd']; 

$sql = "SELECT MAX(ID) AS fd FROM $tempTableName WHERE ID < 3572"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v2 = $data['fd']; 

$sql = "SELECT COUNT(*) AS fd FROM $tempTableName WHERE ID <= 3572"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v3 = $data['fd']; 

$sql = "SELECT COUNT(*) AS fd FROM $tempTableName"; 
$result = odbc_exec($sqlconn, $sql); 
$data = odbc_fetch_array($result); 
odbc_free_result($result); 
$v4 = $data['fd']; 

$sql = "DROP TABLE $tempTableName"; 
$result = odbc_exec($sqlconn, $sql);