2011-03-27 127 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领域占用更少的内存。