【问题标题】:Poor MySQL performance on EC2 Micro instanceEC2 微型实例上的 MySQL 性能不佳
【发布时间】:2013-10-05 16:26:00
【问题描述】:

我有一个小型 webapp,它使用 Pyhon/Flask 和一个 MySQL 数据库来存储数据。我有一个学生数据库,大约有 3000 行。尝试加载该页面时,加载需要很长时间,有时甚至一分钟左右。它大约 20 秒,这真的很慢,我想知道是什么原因造成的。 This 是发出任何请求之前的服务器状态,this 在我尝试加载该站点时发生。

正如我所说,这并没有太多的记录,我很困惑为什么这样无效。我使用的是 Ubuntu 12.04,带有Ver 14.14 Distrib 5.5.32, for debian-linux-gnu (x86_64) using readline 6.2 mysql 版本。其他查询运行良好,例如列出名字以某个字母开头的学生大约需要 2-3 秒,这是可以接受的。这显示了表格的一部分,所以我猜有些东西没有优化。

My.cnf 文件是located here。我尝试了一些东西,在底部添加了一些行,但没有太大的成功。

实际的查询是由 sqlalchemy 完成的,这是用来加载这个的具体代码:

score = db.session.query(Scores.id).order_by(Scores.date.desc()).correlate(Students).filter(Students.email == Scores.email).limit(1)
students = db.session.query(Students, score.as_scalar()).filter_by(archive=0).order_by(Students.exam_date)
return render_template("students.html", students=students.all())

这似乎是生成的 sql:

SELECT student.id AS student_id, student.first_name AS student_first_name, student.middle_name AS student_middle_name, student.last_name AS student_last_name, student.email AS student_email, student.password AS student_password, student.address1 AS student_address1, student.address2 AS student_address2, student.city AS student_city, student.state AS student_state, student.zip AS student_zip, student.country AS student_country, student.phone AS student_phone, student.cell_phone AS student_cell_phone, student.active AS student_active, student.archive AS student_archive, student.imported AS student_imported, student.security_pin AS student_security_pin, (SELECT scores.id \nFROM scores \nWHERE student.email = scores.email ORDER BY scores.date DESC \n LIMIT 1) AS anon_1 \nFROM student \nWHERE student.archive = 0"

提前感谢您的时间和帮助!

【问题讨论】:

  • 您的表上有哪些索引?你能得到 sqlalchemy 生成的实际查询吗?
  • 没有索引,我对使用数据库比较陌生,还没有使用过这些。在问题中添加了炼金术生成的查询。

标签: python mysql ubuntu amazon-ec2 sqlalchemy


【解决方案1】:

@datasage 是对的——微型实例只能做这么多。您可以尝试为您的 mysql 数据库启动第二个微实例。在单个微型实例上同时运行 apache 和 mysql 会很慢。

根据我的经验,在使用 AWS 的 RDS 服务(mysql)时,您可以在微实例上获得合理的性能进行测试。根据实例运行的时间长短,有时您可以让爬虫 ping 您的站点,因此有助于在安全策略中将其 IP 限制到您的计算机。

看起来您的数据库结构并没有那么复杂 - 您可以在电子邮件字段中添加索引,但我怀疑除非您的数据集超过 5000 行,否则不会有太大区别。如果您使用的是 sqlalchemy ORM,则如下所示:

class Scores(base):
    __tablename__ = 'center_master'
    id = Column(Integer(), primary_key=True)
    email = Column(String(255), index=True)

【讨论】:

  • 嘿,我明白了。我可能会尝试下一个实例类型,看看情况如何。至于索引,heidisql 向我展示了这张表:pokit.org/get/img/afa195715379ef93cd1695520a9652c2.jpg 我已经有了。 id = db.Column(db.Integer(11), primary_key=True, autoincrement=True) email = db.Column(db.VARCHAR(60), unique=True) 这算作索引还是我特别需要添加“index=True”部分?
  • 唯一在mysql中作为索引处理,所以不需要加上index=True。查看stackoverflow.com/questions/3127765/… 了解原因。
  • 感谢您的宝贵时间,我会考虑升级 EC2 上的计划。
【解决方案2】:

微型实例的性能相当缓慢。它们采用可突发 CPU 配置文件设计,当超过可突发时间时将受到严格限制。

也就是说,您的问题可能与您的数据库设计有关。任何时候想要连接两个表,都希望在连接的右侧和左侧的列上有索引。在这种情况下,您使用的是电子邮件字段。

使用字符串连接不如使用整数 id 最佳。同样使用Explain 关键字将直接在mysql 中运行查询将显示执行计划,并可以帮助您快速确定可能缺少索引或有其他问题的位置。

【讨论】:

  • 正如我在上一个字段中所说,我将这些电子邮件字段设置为唯一的,当我转到 phpmyadmin/heidisql 中的结构时,我发现这两列已编入索引:pokit.org/get/img/cd44443e715eb50d8630dc0092c89ce4.jpg
  • 也感谢您的意见,正如我在其他评论中所说,我会考虑升级实例类型。
猜你喜欢
  • 2013-05-04
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 2013-07-15
  • 2011-08-19
  • 1970-01-01
  • 2014-08-02
相关资源
最近更新 更多