8.2.1 优化SELECT语句

以SELECT语句为表现形式的查询,执行了数据库中所有的查找操作。调节查询语句,无论对降低动态web页面的响应时间,还是减少夜间大量报告的生成时间,都有着 最高优先级。

除了SELECT语句,这些调优技术也适用于其它一些语句,如CREATE TABLE … AS SELECT, INSERT INTO … SELECT, 以及 DELETE语句中的WHERE条件。这些语句的性能决定因素更多,因为它们不仅有读操作,还有写操作。

NDB集群支持join下推优化,join会被发送到NDB集群中的数据节点,进行并行处理。像了解更多,可以查阅 Conditions For NDB pushdown joins。

优化查询主要考虑一下几个方面:

  • 想要一个SELECT … WHERE语句查询更快,首先要考虑的是你是否可以添加一个索引。在where条件中的相关列上添加索引,可以加速评估、过滤,以及结果集获取。你要在满足应用中的大多数查询需求的情况下建立尽可能少的索引。
  • 对于使用到了joins和外键,涉及多张表的查询来说,索引尤其重要。你可以使用EXPLAIN命令来判断SELECT语句使用了哪些索引。可以查阅8.3.1 “How MySQL Uses Indexes” 以及 8.8.1,”Optimizing Queries with Explain“。
  • 隔离并对查询中的部分进行调优,比如函数调用,会消耗额外的时间。一个函数可能在结果集中的每一行都被调用一次,也可能是在表中的每一行调用一次(这极使得效率被极大地降低),取决于查询被怎样构造,
  • 要减少查询语句中的全表扫描,尤其对大表来说。
  • 定期使用ANALYZE TABLE语句来更新表的统计信息,以便优化器可以制定高效的查询计划。
  • 学习调优技术,索引技术,以及存储引擎相关的特有参数设置。InnoDB引擎和MyISAM引擎都有一系列来使查询高效运行的指导原则,见8.5.6 “Optimizing InnoDB Queries”和8.6.1,“Optimizing MyISAM Queries”。
  • 你可以使用8.5.3 “Optimizing InnoDB Read-Only Transactions” 中的技术来优化只读事务。
  • 在处理查询时,避免使其变得难以立即,尤其是在优化器会自动进行相同转换的情况下。
  • 如果无法只依靠一个优化措施来解决一个性能问题,阅读EXPLAIN计划来裂解查询的内部细节,然后调整索引查询条件,join条件等等。(当你拥有足够的经验时,使用EXPLAIN来读取计划可能是你处理每个查询的首要步骤)
  • 调节MySQL用于缓存的内存大小和属性。通过高效的使用InnoDB 缓冲池,MyISAM的key缓存,以及MySQL的查询缓存,重复缓存可以执行的更快,因为在后面查询时,结果集已经在内存中了。
  • 即使一个查询已经因为使用到了内存缓存而执行得很快,你仍然可以对其进行进一步优化而使其消耗更少的内存。这样可以是你的应用具有多高的可扩展性。可扩展性意味着你的应用可以处理更多的用户,多大的请求而不至于在性能上出现大幅下降。
  • 对于锁问题,查询速度可能会收到同时访问相关表的其它会话的影响。