English 中文(简体)
如何提高MySQL数据库的性能
原标题:
  • 时间:2009-01-16 20:22:22
  •  标签:

How to increase the performance for mysql database because I have my website hosted in shared server and they have suspended my account because of "too many queries" the stuff asked "index" or "cache" or trim my database I don t know what does "index" and cache mean and how to do it on php thanks

问题回答

什么是指数:

把数据库表想象成一个图书馆 - 你有一个大型的书籍集合(记录),每个都有关联的数据(作者姓名、出版商、出版日期、ISBN、内容)。同时假设这是一个非常幼稚的图书馆,所有的书都按照 ISBN(主键)进行排序存放。就像书籍只能有一种物理排序方式一样,数据库表也只能有一个主键索引。

现在设想有个人来到图书管理员(数据库程序)那里问道:“我想知道图书馆里有多少本诺拉·罗伯茨的书。”为了回答这个问题,图书管理员必须要走遍所有书架,并查看每一本书,这非常耗时间。如果图书管理员接到很多这样的请求,那么为了节省时间,他就有必要按作者名字(按姓名建立索引)设置卡片目录 - 然后他就可以通过查阅目录而不是查看书架来更快地回答此类问题。基本上,索引建立了另一种书籍排序方式 - 将它们按作者字母表顺序排列。

请注意,1)建立目录需要时间,2)目录需要额外占用图书馆的空间,3)它会使图书馆添加书籍的过程变得更加复杂 - 图书管理员不仅需要把书按顺序放在书架上,还要填写一张索引卡并将其添加到目录中。同样地,将数据库字段上建立的索引可以加快您的查询,但是索引本身需要存储空间并减慢插入速度。因此,您应根据实际需要创建索引 - 没有必要对您很少搜索的字段进行索引。

缓存是什么:

如果图书管理员有很多人一遍又一遍地询问同样的问题,他也许值得在前台写下答案。他无需检查书库或目录,只需简单地说:“这是我给上一个问这个问题的人的答案”。

在您的脚本中,这可以以不同的方式应用。您可以存储数据库查询的结果、计算或渲染网页的一部分;您可以将其存储到二级数据库表或文件或会话变量或像内存服务的memcached。您可以存储预解析的数据库查询,准备好运行。一些库,如Smarty,将自动为您存储部分或全部页面。通过存储结果并重复使用它,您可以避免多次执行相同的工作。

在每种情况下,您都必须担心答案的有效期限。如果图书馆收到了新书,那该怎么办?使用一个可能已经过时五分钟的答案可以吗?一个过时一天的答案怎么办?

缓存非常应用程序特定;您需要考虑您的数据意味着什么,它有多经常更改,计算的成本高吗,结果多经常需要。如果数据变化缓慢,最好在每次更改时重新计算并存储结果;如果它经常更改但不是关键的话,只有在缓存值超过一定年龄时更新即可。

在本地设置应用程序的副本,启用mysql查询日志并设置xdebug或其他分析器。开始收集数据并测试应用程序。关于如何优化的指南和书籍有很多。重要的是您要花时间测试和收集数据,以便首先优化正确的内容。

使用您收集到的数据,尝试减少每个页面查看的查询次数。理想情况下,您应该能够在不到5-10个查询中获得您所需要的一切。

查看日志,看看你是否两次请求相同的内容。在你的代码的一个部分请求一条记录,然后在几行后再次从数据库请求它,除非你确定值可能已经改变,否则这是一个坏主意。

寻找嵌入循环中的查询,尝试重构它们,使您可以创建单个查询,并简单地对结果进行循环。

你提到使用的select *表明你可能做错了一些事情。你可能应该列出你明确需要的字段。查看此网站或在Google中搜索大量关于为什么“select *是邪恶的”的好论据。

开始查看您的查询,然后对它们使用explain。对于频繁使用的查询,请确保它们使用良好的索引而不是执行全表扫描。调整您的开发数据库上的索引并进行测试。

有几件事情你可以看一看:

  1. Query Design - look into more advanced and faster solutions
  2. Hardware - throw better and faster hardware at the problem
  3. Database Design - use indexes and practice good database design

所有这些说起来都容易做起来难,但这是一个开始。

首先,解雇您的主机,从共享主机转移到您完全控制并有机会适当调整的环境中。

尽可能在实验室中复制该环境,最好使用与生产相同的硬件;这包括RAID控制器等。

我有提到过你需要一个RAID控制器吗?是的,你需要一个。如果没有这个控制器,你无法获得令人满意的写入性能 - 它需要一个带电池备份缓存器。如果没有这个控制器,每次写入都需要物理接触硬盘,这会破坏性能。

无论如何,回到读取性能上,一旦你在实验室里获取了与生产相同规格的RAID控制器(和相同的硬盘,显然),你可以尝试优化一些东西。

更多的内存通常是实现更好性能的最便宜的方法 - 确保您已将MySQL配置使用它 - 这意味着调整存储引擎特定的参数。

我在这里假设您至少有100G的数据;如果没有,请购买足够的内存,使您的整个数据库都适合内存,然后读取性能基本上就解决了。


其他人提到的软件改变,例如优化查询和添加索引,也很有帮助,但是只有当您拥有一个开发硬件环境来让您有意义地进行性能工作 - 即测量应用程序性能有意义 - 这意味着真实的硬件(而非虚拟机),这与生产中使用的硬件环境一致。


哦,对了——还有一件事——不要试图在32位操作系统上部署数据库服务器,这是对好的内存的浪费。

索引是在数据库表上进行的,以加快查询速度。如果你不知道它的意思,那么你没有任何资料。至少,你应该在每个外键和大多数经常在查询的限制条件中使用的字段上建立索引。假设你最初设置了主键,它们应该自动具有索引,我认为不知道索引是什么的人不太可能设置它们。你的表是否已规范化?

顺便说一句,既然你在数学中做除法(为什么我不清楚),你应该搜索整数数学。你可能没有得到正确的结果。

您永远不应该选择*。相反,只选择您在该特定请求中需要的数据。而您在这里的意图是什么?

order by votes*1000+((1440 - ($server_date - date))/60)2+visites600 desc

可能您的查询语句写得不好,和/或有太多查询语句的页面写得不好。您能给我们提供一些经常使用的查询语句的具体示例吗?

sure this query to fetch the last 3 posts

select * from posts where visible = 1 and date > ($server_date - 86400) and dont_show_in_frontpage = 0 order by votes*1000+((1440 - ($server_date - date))/60)*2+visites*600 desc limit 3

你认为怎么样?





相关问题
热门标签