【问题标题】:The best way to handle mysql database with 2.5M entries处理 2.5M 条目的 mysql 数据库的最佳方法
【发布时间】:2013-09-22 19:53:46
【问题描述】:

我正在开发一个程序(基于 Web 的 PHP、MySQL DB),其中包括世界各地所有城市的数据库,包含 250 万个条目(全部在一个表中)。当我尝试从中获取详细信息时,服务器(假设 localhost,wamp)花了很多时间来搜索和获取数据。 我在互联网上搜索以找到使用如此大数据的最乐观方法。 我认为,一种方法是将此表缩小为每个国家/地区的不同表,以简化搜索过程。

谁能建议如何处理这个问题并分享知识?

编辑: 该表包括两列。 1.country 2.city。我使用WHERE country=XX 使搜索过程更容易,但是需要很长时间才能处理。

数据库:(表名:cities

country city
US  Lakewood Estates
US  Lakewood Estates Mobile Home Park
US  Lakewood Falls
US  Lakewood Forest
US  Lakewood Gardens
US  Lakewood Harbor
US  Lakewood Heights
US  Lakewood Highlands
US  Lakewood Hills
.
.
.

PHP 代码:

$data = mysql_query( "SELECT * FROM cities where country='".mysql_real_escape_string($_GET['country'])."' ORDER BY country" )
        or die( mysql_error() );

$i = 0;
while( $row = mysql_fetch_array( $data )){
    if ( strpos( strtolower( $row['city'] ), $q ) !== false ) {
        $i++;
        $arr[] = $row['city'];
        if ($i==10) {break;}
    }
}

echo "[";
for ($x=0; $x<count($arr); $x++)
  {
  echo '{"name":"'.$arr[$x].'"}';
   if ($x!=count($arr)-1) {echo ',';}
  }
echo "]";

【问题讨论】:

  • 不是那么多,即使在 VPS 上的 MySQL 也可以处理更多。但不要忘记索引和优化查询。
  • 请添加您的表结构和查询。这样我们就可以看到您缺少索引的位置以及您如何检索数据。
  • 索引可能会对您有所帮助。
  • 使用LIMIT 10 而不是if ($i==10) {break;} 可能更明智

标签: php mysql large-data


【解决方案1】:

250 万个条目实际上并没有那么多。您需要根据检索数据的方式(where 子句)添加适当的索引,这样会更快。

像这样在国家/地区添加索引(首先您需要将列数据类型更改为varchar

ALTER TABLE cities MODIFY COLUMN country varchar(255);

ALTER TABLE cities
ADD INDEX country_idx (`country`);

【讨论】:

  • 该表包括两列。 1.国家 2.城市。我使用WHERE country=XX 使搜索过程更容易,但是需要很长时间才能处理。
  • 我得到了这个:#1170 - BLOB/TEXT 列“国家”在没有密钥长度的密钥规范中使用
  • 啊,我明白了。您不能在 text 列上添加索引,因为它们太长了。对于您的需要,VARCHAR(255) 就可以了。所以先把列类型从text改成VARCHAR(255)再添加索引。
  • @ImanHejazi:我知道这是很大的改变,但我相信这是值得的。
【解决方案2】:

执行以下操作以仅检索 10 个值可能更明智,但我可能错了吗?因为您正在检索所有记录 WHERE country = XX 并且仅使用前 10 条返回的记录并丢弃其余记录。返回一个国家/地区的所有记录可能会减慢您的查询速度。

SELECT * FROM cities where country='".mysql_real_escape_string($_GET['country'])."'
ORDER BY country LIMIT 10 (or what ever you want to limit to)

while( $row = mysql_fetch_array( $data )){
    if ( strpos( strtolower( $row['city'] ), $q ) !== false ) {
        $i++;
        $arr[] = $row['city'];
        if ($i==10) {break;}#remove this line
    }
}

也可能切换 MySQL 引擎可能会提高执行。

【讨论】:

  • 感谢您的回复。 LIMIT 10 到底是做什么的?选择了哪 10 个项目?当我设置LIMIT = 10 时,结果会消失。
  • @ImanHejazi LIMIT 10 在排序/分组后返回前 10 个结果,= 也不应该在 LIMIT 中,它必须是查询中的最后一项
  • 抱歉= 输入错误。我正在考虑这个问题。
  • 但是我想在所有记录之间搜索,而不是前 10 个。如果我使用这个例如:SELECT * FROM cities where country='US' ORDER BY country LIMIT 10 搜索总是会在表的前 10 个城市(包括美国)之间执行跨度>
  • @ImanHejazi 不,它只会在搜索和排序后返回前 10 条记录。如果你想要页面或类似的创建一个函数,将 LIMIT 更改为 LIMIT 0,10 从记录 0 开始,并为第 1 页和第 2 页提供 10 条记录 LIMIT 11,10 从记录 11 开始,有 10 条记录,等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多