PHP / MySQL - 性能考虑因素查询(仅选择)48k行

时间:2011-06-02 10:57:42

标签: php mysql

我目前正在尝试构建一个非常依赖邮政编码数据的Web应用程序(由OS CodePoint Open提供)。邮政编码数据库有120个表,它们分解了初始邮政编码前缀(即SE,WS,B)。在这些表中,有11k到48k行,有3个字段(Postcode,Lat,Lng)。

我需要做的是让用户上线,输入他们的邮政编码,即SE1 1LD然后选择SE表,并将邮政编码转换为lat / lng。

我在PHP级别上这样做很好。我担心的是......很多行会被查询,是否会让我的网站停止运转?

如果有任何我应该了解的技巧,请告诉我。我从未使用过大数字的表格!

谢谢:)

4 个答案:

答案 0 :(得分:4)

48K不是大数字。 4800万是。 :)如果你的表被正确编入索引(在你在WHERE子句中使用的字段上放置索引),它根本不会成为问题。

避免使用LIKE,如果可能,请使用INNER JOINS而不是LEFT JOIN。

答案 1 :(得分:4)

在mysql中从48k行中选择并不大,实际上它相当小。正确索引并且你很好。

答案 2 :(得分:1)

如果我理解正确,则会有一个SE表,一个WS,一个B等。总之, 120个具有相同结构的表 (Postcode, Lat, Lng)

我强烈建议您规范化表。

您可以拥有一个表格:

postcode( prefix, postcode, lat, lng)

或两个:

postcode( prefixid , postcode, lat, lng )

prefix( prefixid, prefix ) 

邮政编码表将比11K-48K行大,大约30K x 120 = 3.6M行,但是如果您想搜索,它将节省您为每个前缀写入不同查询的时间和相当复杂的查询纬度和经度(想象一下在120个表中搜索的查询)。

如果您不相信尝试添加person表,以便为用户添加数据。该表如何与邮政编码表相关?


修改

由于prefix只是postcode的第一个字符primary key,因此不需要额外的字段或第二个表。我只想将120个表合并为一个:

postcode( postcode, lat, lng )

然后查询:

SELECT * 
FROM postode
WHERE postcode = 'SE11LD'

SELECT * 
FROM postode
WHERE postcode LIKE 'SE%'

会很快,因为他们将使用主键索引。

答案 3 :(得分:0)

只要您在相应的列上有索引,就应该没有问题。我的一位客户将邮政编码数据库存储在如下表中:

CREATE TABLE `postcode_geodata` (
`postcode` varchar(8) NOT NULL DEFAULT '',
`x_coord` float NOT NULL DEFAULT '0',
`y_coord` float NOT NULL DEFAULT '0',
UNIQUE KEY `postcode_idx` (`postcode`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |

在查询时我们没有问题(从性能的角度来看)。

如果你的表变得非常大,那么你总是可以看看使用MySQL的分区支持 - 请参阅http://dev.mysql.com/doc/refman/5.1/en/partitioning.html - 但在你先完成更简单的事情之前我不会看到它(见下文)

如果您认为性能是一个问题,请打开MySQL的slow_query_log(请参阅/etc/mysql/my.cnf)并查看它的内容(您可能还会发现命令'mysqldumpslow'此时用于分析慢查询日志)。

还尝试在MySQL cli上使用'explain'语法 - 例如

EXPLAIN SELECT a,b,c FROM table WHERE d = 'foo' and e = 'bar'

这些步骤将帮助您优化数据库 - 通过识别哪些索引(或不是)用于查询。

最后,还有mysqltuner.pl脚本(参见http://mysqltuner.pl),它可以帮助您选择MySQL服务器的设置(例如查询缓存,内存使用等会影响I / O,从而影响性能/速度)。