会员表自动补充,速度慢

时间:2012-01-30 10:09:16

标签: php mysql

补充作品形式的自动会员资格迟到了。数据库缓慢。有没有办法加快这个?用户无所谓..如何停止写自动补充?(自动补充;城市输入。会员表格。)

Register.php

 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript" src="jquery.autocomplete.js"></script>
 <script type="text/javascript">
 $().ready(function() {
 $("#sehir").autocomplete("CityAutoComp.php", {
    width: 312,
    matchContains: true,
    mustMatch: true,
    //minChars: 0,
    //multiple: true,
    //highlight: false,
    //multipleSeparator: ",",
    autofill:true,
    selectFirst: false
 });
 });
 </script>

CityAutoComp.php

 <?php 
 session_start();
 ob_start();

 $con = mysql_connect("localhost","******","****");
 if (!$con)
   {
 die('Could not connect: ' . mysql_error());
 }
 mysql_select_db("*****", $con);
 $q = strtolower($_GET["q"]);
 if (!$q) return;

 $sql = "select DISTINCT city from location where city LIKE '%$q%'";
 $rsd = mysql_query($sql);
 while($rs = mysql_fetch_array($rsd)) {
 $cname = $rs['city'];
 echo "$cname|$\n";
 }
 ?>

 ---
 <tr>
 <th>City:</th>
 <td><input id="sehir" autocomplete="off" name="sehir" type="text" style="text-transform:      capitalize" class="inputbox" size="45" value="<?php echo post('sehir');?>" /></td>
 </tr>

尊重。 (我为我的英语道歉。)

3 个答案:

答案 0 :(得分:1)

首先你应该摆脱SQL注入,这是escaping functions的内容(在提到的页面上有一些很好的例子)或者你可以使用placeholders in PDO expressions(再看看例子)。

关于速度,您在其中一条评论中提到了大约1000条记录。对于mysql数据库来说这真的不应该是问题(即使表格设计很糟糕)。所以我假设你有慢速数据库服务器(在许多网站之间共享,过载,远程连接速度慢)。这可以通过在php中实现缓存来解决。将数据存储在文本文件中,或直接存储在php文件中,如下所示:<?php return array( ...); ?>(这实际上是丑陋的解决方案,但它是最简单的,php cache的谷歌可以获得更相关的结果)。

第二个可能的问题是用户和服务器之间的连接速度缓慢(您的服务器或用户具有低带宽,长延迟等)。这可以通过加载.js文件来修复,该文件将包含所有城市,例如JSON格式。 此解决方案仅适用于数百甚至数千条记录,我不会超过5KB文件。

最后。假设您的表中有50万条记录,并且由于数据量的原因,您的查询需要很长时间。修复性能的第一步是将%$q%更改为$q%(这要求用户正确写出第一个字母,而不仅仅是任何字母)。

第二步是要求用户在加载自动填充之前键入(比方说)3个字符。第三步将利用前两个步骤,并严重提高您的请求的性能。第一部分:添加包含前三个字段的字段(用户输入所需的数字)字母。

ALTER TABLE `locations` ADD `characters` CHAR(3) AFTER `city`;

第2部分,添加索引,允许mysql快速直接访问这些记录:

ALTER TABLE `locations` ADD INDEX (`characters`);

假设用户想要输入Paris。他/她输入3个字母(标准杆)。 SQL查询将包含条件:

SELECT `city` FROM `locations` WHERE `characters` = '$q';

这应该在explain语句中创建USING INDEX而不是BROWSING ALL RECORDS(当你有50万条记录而且只有30条以par开头时,这就是性能提升的地狱)。当然整个查询看起来像(假设$q = substr( $qFull, 0, 3)):

SELECT `city` FROM `locations` WHERE `characters` = '$q'
                               AND `city` LIKE '$qFull%';

你差不多完成了,但是你需要更新characters列,这可以通过以下方式完成:

UPDATE `locations` SET `characters` = `city`; -- Or:
INSERT INTO `locations` (`city`, `characters`) VALUES ( '$city', '$city');

(别担心,mysql会自动裁剪数据以适应CHAR(3)

答案 1 :(得分:0)

尝试将sql查询更改为

"select city from location where city LIKE '%$q%' LIMIT 1"

这会稍微提高性能。它可能会对结果产生影响,所以我会在常用名称上进行测试。

答案 2 :(得分:0)

问题不是很明确,但试图回答它。我没有给你一个完整的修复,因为这根本不会培养开发人员的能力。

您的代码非常容易受到SQL注入攻击,这是首先要考虑的问题。在这种情况下,$ q是危险的。此外,您不会检查您的查询是否成功。

echo "$cname|$\n";

对我来说这是一些奇怪的代码,建议的输出是什么?类似的东西:

New York|1

或者您还需要其他结果吗?这可能没问题,但我的感觉反过来说:1 |纽约更合乎逻辑。

建议的SQL:

select city from location where city LIKE '%$q%' LIMIT 1

当你想要多个结果但每个城市只有一次时,会给你留下最多1个结果,这是正确的吗?

在文件中:CityAutoComp.php为什么需要ob_start(),为什么有表行代码?该文件只能输出它直接找到的结果。保持这一点很简单。

关于速度问题,您应该使用一些调试器(例如浏览器)来查看延迟发生的位置。在测试旁边:microtime()可能会为您提供延迟的具体位置:http://php.net/manual/en/function.microtime.php

例如,将它放在查询周围,看看这是否真的是问题。

一般情况下,缓存可能对这些结果有好处,但实际上取决于您的情况,可能会发现根本不需要缓存,或者所有结果都应该是实时的。那时缓存可能会变得非常昂贵。所以在添加更多复杂性之前先进行测量。