2016-04-25 45 views
0

對於輸入提示搜索(當您鍵入到它顯示的表單中的匹配項在下拉列表中匹配時),我有以下查詢。這個查詢運行良好,直到我切換到大約一百萬條記錄的數據庫。現在需要15秒才能顯示比賽。 由於搜索匹配在鍵入時顯示,查詢位於循環內。是否有任何關於這個查詢可以改變以加快速度?使用mysql提高數據庫查詢的速度

$diagnosis = isset($_GET['diagnosis']) ? $_GET['diagnosis'] : ''; 

$data = array(); 

if ($diagnosis) { 
$query = explode(' ', $diagnosis); 

for ($i = 0, $c = count($query); $i < $c; $i ++) { 
    $query[$i] = '+' . mysql_real_escape_string($query[$i]) . '*'; 
} 

$query = implode(' ', $query); 

$sql = "SELECT diagnosis, icd9, MATCH(diagnosis) AGAINST('$query' IN BOOLEAN MODE) AS relevance 
     FROM icd10 WHERE MATCH(diagnosis) AGAINST('$query' IN BOOLEAN MODE) HAVING relevance > 0 ORDER BY relevance "; 

$r = mysql_query($sql); 

    while ($row = mysql_fetch_array($r)) { 
     $data[] = $row; 
    } 
} 

echo json_encode($data); 
exit; 
+0

請提供以前和當前服務器設置的詳細信息 – Drew

+2

**警告**:如果您剛學習PHP,請不要學習過時的['mysql_query'](http://php.net/ manual/en/function.mysql-query.php)接口。這很糟糕,並且已經在PHP 7中被刪除了。像[PDO不是很難學的東西](http://net.tutsplus.com/tutorials/php/why-you-should-be-using-php-pdo- for-database-access /)以及[PHP The Right Way](http://www.phptherightway.com/)等指南有助於解釋最佳實踐。你的用戶參數是** not ** [正確轉義](http://bobby-tables.com/php),你在這裏有嚴重的[SQL注入漏洞](http://bobby-tables.com/)。 – tadman

+0

我知道這是貶值。然而,如果我升級我的PHP,我將不得不經歷約300頁充滿mysql查詢和chnage他們,因爲我認爲,當我升級,整個網站將無法正常工作,除非我改變每一個查詢。 – user2557039

回答

1

你可以嘗試一些東西:

首先,確保你有一個全文索引diagnosis。其次,確保你有一個全文索引diagnosis!一百萬行並不是那麼多(當然,取決於diagnosis中的單詞數量),所以已經可能是問題。

那就試試下面的代碼:

SELECT diagnosis, icd9, MATCH(diagnosis) AGAINST('$query' IN BOOLEAN MODE) AS relevance 
FROM icd10 ORDER BY relevance desc limit 30 

(它可能不是很明顯,這是更快,它可能不是,所以只是嘗試一下)。

如果您需要支持簡短的單詞,例如如果經常輸入3位icd9碼,你應該檢查你的ft_min_word_len/innodb_ft_min_token_size-values(取決於你的數據庫)以確保它們包含在索引中 - 但要注意它會增加你的索引大小。也許檢查停用詞。

您沒有指定您的設置;您通常可以通過例如提高通用數據庫性能更改設置,硬盤或內存。尤其是內存。

一些一般想法:您可能想要異步調用該函數(用戶應能夠在查詢運行時鍵入)。只要你打不到30個結果(或者你設置的任何限制),你就可以在php中隨時過濾剩餘的結果(只要查詢得到更長的時間/沒有文字被刪除) - 這是最接近你的結果一個緩存。或者將限制設置爲1000,然後手動過濾,php正則表達式也很快,你只需要一個分數函數。 根據您的數據,當您只向查詢添加單個字母(每個文本將包含以「a」開頭的單詞時,您可能不想運行查詢),因此您可能得不到更好的結果 - 可能不會雖然是「q」的情況)。這不會減少查詢的運行時間,但您可以保存一次執行。

+0

非常感謝您的深入回覆。我會先嚐試LIMIT 30的事情。注意診斷被索引,但不確定它是否爲「全文」索引。 – user2557039

+0

嘗試'SHOW INDEX FROM IDC10;',它會列出索引;在'index_type'下你應該看到'FULLTEXT'。 – Solarflare