如何提高mysql查询的性能?

时间:2011-03-27 17:27:51

标签: php mysql

我正在使用此查询使用ajax检查用户名是否已存在于数据库中 所以直到现在我在数据库bt中只有很少的记录在未来的用户名列表中会很大,所以我想以这样的方式提高查询的性能,这将花费更少的时间来检查用户名的存在。

如何改进以下查询?对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>

6 个答案:

答案 0 :(得分:4)

在vector.signup表的 userid 列上创建索引可能会解决您的性能问题。

目前,您的脚本中存在严重的安全漏洞。您永远不应该将POST数据直接注入到查询中,因为您可以自行打开SQL注入攻击。您应该首先转义数据:

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

您可以在这里阅读更多内容:

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

答案 1 :(得分:2)

是的,您应该在userid字段上添加索引。对于mysql,它看起来像这样:

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

编辑:一旦连接到数据库,就可以在MySQL控制台中使用此行。如果您使用的是PHPMyAdmin,它还支持在GUI中添加索引。

答案 2 :(得分: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";

}
?>

答案 3 :(得分:1)

有两种用例:

1)如果您不介意搜索用户名的最终用户可以使用的用户列表,您可以一次性获取完整列表并使用javascript函数为用户提供每个按键的选项。 / p>

2)如果你不想给最终用户完整列表,你可以放心使用你正在使用的方法。只需要在用户名上编制索引。即使对于数百万条记录也是如此。

谢谢,

Shashwat

答案 4 :(得分: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>

答案 5 :(得分:1)

你不能优化查询本身,因为它只是搜索列中的id,而这就是必须要做的事情。但是您可以向列添加索引,因此您的dbms准备好有效地搜索列。你可能会选择使用iso-whatever而不是utf-8。然后排序对你的db来说会更快,b / c该字段占用的内存更少。