如何避免mysql DB的高负载?
Posted
技术标签:
【中文标题】如何避免mysql DB的高负载?【英文标题】:high load on mysql DB how to avoid? 【发布时间】:2010-12-19 10:59:42 【问题描述】:我有一张表,其中包含世界各地的城市,其中包含 70,000 多个城市。
并且在我的主页中也有自动建议输入 - 它在我的主页中大量使用 - 为输入中的每个输入(在第二个字母之后)进行 sql 查询(如搜索)..
所以我担心负载过重,...,所以我正在寻找任何解决方案或技术可以在这种情况下提供帮助。
【问题讨论】:
【参考方案1】:缓存表,最好在内存中。 70.000 个城市并没有那么多数据。如果每个城市占用 50 个字节,那就只有70000 * 50 / (1024 ^ 2) = 3MByte
。毕竟,城市列表不会那么快速变化。
如果您只使用 AJAX 调用,您可以缓存 JSON 中前两个字母的每个组合的数据。假设一个类似拉丁字母的字母表,这将是大约 680 种组合。将它们中的每一个保存到 JSON 格式的文本文件中,并让 jQuery 直接访问文本文件。
【讨论】:
thanx,我喜欢使用 JSON 的想法,比其他的更高效? 我假设您已经在使用 JSON 格式的消息,因为这是用于 AJAX 数据传输的最常用格式。 JSON 格式很简洁,在 javascript 中可以非常快速地解析,并且在 jQuery 中有很好的支持。但是,任何其他格式都可以以相同的方式缓存在服务器上。因此,如果您更喜欢其他格式,请选择它。【参考方案2】:首先在城市“名称”上创建索引。这加快了如下查询:
SELECT name FROM cities WHERE name LIKE 'ka%'
还可以尝试让您的自动完成表单有点“懒惰”。用户输入的字母越多,您的数据库必须处理的记录数就越少。
【讨论】:
问题是我使用像'%ka%'这样的查询【参考方案3】:What resources exist for Database performance-tuning?
【讨论】:
【参考方案4】:您应该在网络服务器上缓存尽可能多的数据。国家、城市等列表等不经常变化的数据是一个很好的候选者。实际上,您多久添加一次国家/地区?即使您更改了列表,缓存的简单刷新也将处理此问题。
您应该确保正确调整查询以充分利用索引和连接技术。
您的数据库也可能有来自其他查询的负载。您可能想研究提高 mysql 数据库性能的技术。
【讨论】:
【参考方案5】:只需让您的表适合内存,这对于 70k 行来说应该是微不足道的。
然后您可以非常轻松地进行扫描。也许甚至不为此使用 sql 数据库(因为它不会经常更改),只需将城市转储到文本文件中并扫描即可。如果您有许多 Web 服务器但只有一个 db 服务器,那肯定会更好,因为每个服务器都可以保留自己的文件副本。
您看到峰值每秒有多少查询?我无法想象有这么多人输入城市名称,即使它是一个非常繁忙的网站。
如果您获得良好的命中率(例如,因为人们倾向于输入相同的内容),您还可以缓存单个响应(例如在 memcached 中)
实际上,您也可以预先计算所有一三个字母组合的响应,即只有 26*26*26 (=17k) 个条目。由于四个或更多字母输入在逻辑上必须是其中之一的子集,因此您可以扫描 17k 条目中的适当一个。
【讨论】:
【参考方案6】:如果你有城市名称的索引,它应该被数据库有效地处理。这个说法是错误的,见下面的cmets
为了降低对服务器资源的需求,您可以仅在 n 个字符后提供自动完成功能。还允许一些超时,即当用户仍在输入时不要发出请求。 一旦用户停止输入一段时间,您就可以请求自动完成。
【讨论】:
我在 2nd leeter 之后使用过,icann 不会超过这个数字。此外,超时的想法会给脚本增加额外的延迟,这是不可接受的,thanx man。 不,索引只会提高精确匹配和范围查询的性能,而不是子字符串匹配(例如,使用 LIKE '%ka%')以上是关于如何避免mysql DB的高负载?的主要内容,如果未能解决你的问题,请参考以下文章
利用keepalived和haproxy配置mysql的高可用负载均衡