2011-03-27 187 views
2

我正在使用此查詢來檢查用戶名是否已存在或不在數據庫中使用ajax 因此,直到現在我只有幾個記錄數據庫bt在未來的用戶名單將是巨大的,所以我想提高查詢的性能這樣一來,檢查用戶名存在將花費更少的時間。如何提高mysql查詢的性能?

我該如何改進以下查詢?對db的索引是可行的解決方案嗎?

check.php 

<?php 
if(isset($_POST['user_name'])) 
{ 
$user_name=$_POST['user_name']; 
include("include/conn.php"); 
$sql_check = mysql_query("select userid from `vector`.`signup` where userid='".$user_name."'") 
or die(mysql_error()); 

if (mysql_num_rows($sql_check)>0) 
{ 
    echo "no"; 
} 
else 
{ 
echo "yes"; 
} 
} 
?> 

my jquery code 

<script language="javascript"> 

$(document).ready(function() 
{ 
    $("#uname").blur(function() 
    { 
       $("#msgbox").removeClass().addClass('messagebox').text('Checking...').fadeIn("slow"); 

     $.post("check.php",{ user_name:$(this).val() } ,function(data) 
     { 
      if(data=='no') //if username not avaiable 
      { 
      $("#msgbox").fadeTo(200,0.1,function() 
      { 

       $(this).html('This User name Already exists').addClass('messageboxerror').fadeTo(900,1); 
      });  
      } 
      else 
      { 
      $("#msgbox").fadeTo(200,0.1,function() 
      { 

       $(this).html('Username available to register').addClass('messageboxok').fadeTo(900,1);  
      }); 
      } 

     }); 

    }); 
}); 
</script> 
+0

是的,把一個索引放在'userid'上。(編輯,是的,對不起,在where子句中。 – 2011-03-27 17:29:14

+0

@Adam這是不正確的意思列。@eclair您需要創建用戶標識的索引。如果用戶ID是你的主鍵,然後指數會被自動創建。 – 2011-03-27 17:31:53

+0

@Adam,我假設你的意思的用戶ID? – 2011-03-27 17:32:03

回答

2

是的,你應該在用戶ID字段添加一個索引。對於MySQL,這將是這個樣子:

ALTER TABLE `vector`.`signup` ADD INDEX(userid); 

編輯:您可以使用此行MySQL控制檯一旦你連接到數據庫。如果您使用PHPMyAdmin,它也支持在其GUI中添加索引。

+0

以及如何做到這一點,我應該使用在上面的代碼中該查詢還是應該解僱這在MySQL控制檯 – 2011-03-27 17:39:15

+0

感謝我試圖儘快 – 2011-03-27 17:42:14

+0

你們我沒有查詢成功執行,現在我怎麼能檢查我的查詢性能提高將回復? – 2011-03-27 17:43:33

1

有兩個用例:

1)如果您不介意提供給最終用戶的用戶誰是搜索的用戶名列表,你可以一氣呵成獲取完整列表使用javascript函數爲用戶提供每個按鍵上的選項。 2)如果你不想給最終用戶完整列表,你可以放心使用你正在使用的方法。只需在用戶名上建立索引。即使對於數百萬條記錄,它也會足夠快。

感謝,

Shashwat

+0

請不要做數。 1.如果您的表格足夠大以至於需要在名稱字段上建立索引,那麼將整個表格轉儲到發送給客戶端的數據當然不會更好。 – Collin 2011-03-27 17:40:07

4

創建的vector.signup表的用戶ID列的索引可能會解決您的性能問題。

就目前而言,您的腳本中存在嚴重的安全漏洞。你不應該直接將POST數據注入到查詢中,因爲你打開自己的SQL注入攻擊。你應該首先逃避你的數據:

$ user_name = mysql_real_escape_string($ _ POST ['user_name']);

你可以在這裏閱讀更多:

http://php.net/manual/en/function.mysql-real-escape-string.php

+0

謝謝我做了更改 – 2011-03-27 17:39:36

+0

根據其他響應,userid是主鍵字段,隱含索引已存在。唯一可用於提高性能的其他可行機制是將LIMIT 1附加到查詢中,使用表分區或利用基於整數的主鍵。 – 2011-03-27 17:41:53

1

您可以在用戶輸入時將請求延遲到服務器。只有當沒有按鍵按下至少一秒時,以下示例纔會調用myAjaxFunc函數。 (所以在打字時沒有呼叫呼叫呼叫。)

<input type="text" name="username" onkeypress="ajaxRefresh()"> 

<script> 
    window.ajaxTimeout = false; 

    function ajaxRefresh() { 
     if (window.ajaxTimeout) { 
      clearTimeout(window.ajaxTimeout); 
      window.ajaxTimeout = false; 
     } 
     window.ajaxTimeout = setTimeout(myAjaxFunc, 1000); 
    } 

    function myAjaxFunc() { 
     // do your AJAX stuff 
    } 
</script> 
2

你真的需要關注的安全性,性能和組織作爲一個開發者。以下是我將如何重新編寫代碼以使其更易於閱讀和更安全。希望它可以幫助你:

<?php 

$strUsername = isset($_POST['user_name']) ? $_POST['user_name'] : NULL; 

if(!empty($strUsername)) { 

    require("include/conn.php"); // Consider using require_once() if it makes sense 

    $objResults = mysql_query(sprintf('SELECT userid 
           FROM vector.signup 
           WHERE userid = "%s" 
           LIMIT 1', mysql_real_escape_string($strUsername))); 

    if ($objResults === FALSE) { 

     // Log the mysql_error() (dont show it to the user for security reasons) 
     exit('Insert user friendly error message'); 

    } else { 

     if (mysql_num_rows($objResults) === 1) { 

      echo "Yes"; 

     } else { 

      echo "No"; 

     } 

    } 

} else { 

    echo "Invalid input error message"; 

} 
?> 
+0

我試過這段代碼,但它似乎不適用於我的案例 – 2011-03-27 18:06:34

+0

您是否收到任何類型的錯誤信息或只是一個白屏? – 2011-03-27 18:10:16

+0

使用上面的代碼我送沒有和是到jQuery代碼,顯示消息的用戶名命名的存在與否BT似乎不工作 – 2011-03-27 18:28:25

1

無法優化查詢本身,因爲它只是在尋找FO一列中的ID,這就是有許多工作要做。但是您可以向該列添加索引,以便您的dbms準備好有效地搜索列。你可以選擇使用iso-whatever而不是utf-8。然後排序將更快爲您的分貝,B/C領域佔用更少的內存。