更好/更快地搜索81k +城市以及来自json / mySQL的建议组合框

时间:2016-06-22 01:34:12

标签: php json autocomplete

确定。问题是 - 你要看的代码是100%工作但是,开始显示建议需要永远。我注意到我是否可以调整它以仅在第5个字符后开始搜索它将加载更快。我从https://daveismyname.com/autocomplete-with-php-mysql-and-jquery-ui-bp

改编了这段代码

我虽然因为我处理超过81,000行,mySQL会更快。现在我在本地主机。这些数据来自美国所有城市的公共记录。

问题1:您认为上传到我的网站主机后会更好吗?

问题2:是否有更好的方法可以更快地完成这项工作

问题3:我如何测试$ _POST是否超过5位

的index.php

<head>
  <meta charset="utf-8">
  <title>Demo</title>
  <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/themes/base/minified/jquery-ui.min.css" type="text/css" />
</head>
<body>
    <form action='' method='post'>
        <p><label>City or Zip Code: </label><input type='text' name='city' class='auto'></p>
    </form>
<!-- Those lines are mandatory in order to use JQuery and JQuery UI  -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.1/jquery-ui.min.js"></script>

<script type="text/javascript">
$(function() {
    //autocomplete
    $(".auto").autocomplete({
        source: "search.php",
        minLength: 1
    });

});
</script>

的search.php

<?php
// https://daveismyname.com/autocomplete-with-php-mysql-and-jquery-ui-bp
define('DB_SERVER', 'localhost');
define('DB_USER', 'username');
define('DB_PASSWORD', 'password');
define('DB_NAME', 'us_cities');
if (isset($_GET['term'])){
    $return_arr = array();

    try {
        $conn = new PDO("mysql:host=".DB_SERVER.";port=8889;dbname=".DB_NAME, DB_USER, DB_PASSWORD);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // $stmt = $conn->prepare('SELECT country FROM countries WHERE country LIKE :term');
        $stmt = $conn->prepare('SELECT city FROM cities WHERE city LIKE :term');
        $stmt->execute(array('term' => '%'.$_GET['term'].'%'));

        // BE AWARE
        while($row = $stmt->fetch()) {
            $return_arr[] =  $row['city'];
        }

    } catch(PDOException $e) {
        echo 'ERROR: ' . $e->getMessage();
    }

    /* Toss back results as json encoded array. */
    echo json_encode($return_arr);
}
?>

1 个答案:

答案 0 :(得分:0)

我遇到了类似的问题。用户输入字符后,以下原因导致大部分延迟

  1. 连接服务器并发送查询的时间
  2. PHP连接数据库并执行查询所需的时间
  3. 因此,为了产生重大影响,您的度量应该减少与服务器的连接数,减少数据库执行次数或使用更快的数据库查询。您可以采用至少3种方法来显着减少延迟。他们甚至可以合并。

    方法1:加快数据库查询速度

    1. 更改数据库表结构,使cities字段的索引类型为FULLTEXT。这些是专门设计为speed up text search。 Thiis要求您的表使用InnoDB存储引擎,而不是旧的MyISAM。要弄清楚你拥有或改变它,check this out

    2. 更改您的SQL查询以使用MATCH() AGAINST来搜索而不是LIKE。例如:SELECT city FROM cities WHERE MATCH(city) AGAINST ('term')More info here。您需要完成第1步才能使其正常工作

    3. 方法2:减少http请求数量

      1. 在表单中添加STATE下拉列表,并在数据库中添加STATE字段。当用户选择状态时,进行查询以将该状态中的所有城市名称提取到浏览器。这将是1或2,000条记录。如果在将结果返回浏览器之前对结果进行gzip压缩,则结果将低于100KB。此时用户会有延迟,但由于用户尚未输入城市名称并等待自动填充,因此不会有什么大不了的。
      2. 现在您已将浏览器中的结果作为Javascript城市数组,您可以将数组提供给autocomplete jQueryUI函数。将minLength设置为3,自动完成延迟将会很短,以至于用户无法察觉它。
      3. 方法3:减少数据库查询次数

        如果您不想下载大量结果,可以采取其他方法;自动填充功能不会像之前一样快,但速度会比您目前的速度快:

        1. 安装并使用内存缓存。如果将所有城市缓存在内存中,您将能够快速找到结果而无需查询数据库。我会查看PHP的MemcacheMemcached扩展,以获得更好的选择。在我自己的研究中,我发现第二个功能更完整,但我选择了第一个,因为它是我在Windows上运行的唯一一个(在我的开发机器上)

        2. 当查询进入时,首先检查cities列表是否已在缓存中。如果是,请使用array_filter()创建匹配数组echo。如果cities不在缓存中,请执行数据库查询以加载缓存中的所有城市,然后使用array_filter(),如上所述。您可以通过在数据库中添加STATE输入,STATE字段,并将每个州的城市存储为缓存中的不同条目来节省更多时间。因此,当用户在纽约搜索某个城市时,您不必在所有81,000个城市中运行array_filter()

        3. 我自己的建议是你将所有3种方法结合起来(除非带宽是一个大问题,在这种情况下你可能想跳过#2)。第三种方法有点工作,因为它需要一些研究和安装,但是一旦你有一个工作缓存,你就会发现你可以使用它来加速缓慢移动数据的大量操作(例如:您过去常常查询数据库的城市名称没有太大变化。