尽管经验让智慧成熟,但至少必须从某些方面着手。例如,您必须了解查询设计的关键注意事项,查询的内部执行方式,失败的地方,优化模式等。在本文中将提供一些优化点,供在MySQL中设计查询时考虑。
为什么某些查询变慢?
SQL查询的一个常见问题是,检索到的数据多于实际需要的数据。当然,有些查询会筛选大量数据,我们无法对其做很多事情,但是它们并不常见。在大多数情况下,糟糕的查询设计会导致查询性能下降。在每次查询设计之后,您都必须对以下两个方面进行内省:触发查询后会发生什么:
- SQL查询会访问太多的列或行吗?
- MySQL服务器会分析太多的行来检索所需的结果吗?
有些查询使MySQL服务器对太多数据进行分析,但在筛选时将其抛出。从许多方面来看,这是服务器的一项额外工作,例如网络开销,服务器上过多的内存消耗或过多的CPU资源使用。结果是性能降低。
在某些情况下,您可能无法在设计过程中提供很多帮助,但是在某些情况下,如果您谨慎并估计结果和内省,那么至少可以提出一个不好的查询,如果不是更好的话。
典型错误及其解决方案
编写查询时经常犯很多常见的错误。这里有几个。您可以在同一行上找到更多思考。这是使用可能的解决方案降低查询性能的原因。
行太多
错误通常是由于编写查询来检索数据并假定MySQL将按需提供结果,而忽略了返回完整结果集所需的处理量而引起的。假设,当实际上只需要首先显示其中的10个产品时,会激发SELECT语句以获取一个电子商务网站的100个产品详细信息。您可能会认为MySQL仅获取10行并停止执行查询。但不是。MySQL所做的是生成完整的结果集并提供给客户端。客户端库将接收完整的集合,并丢弃其中的大部分,并且仅保留其中要查找的10个集合。这显然浪费了很多资源。
但是,在这种情况下,可以通过对查询使用LIMIT子句来提供解决方案。
选择
col1,col2,…
从
table_name
限制
[偏移,]计数;
LIMIT子句接受一个或两个参数。第一个指定偏移量,第二个指定计数。如果仅指定一个参数,则表示从结果集开始的行数。
例如,要从表中选择10行,您可以编写:
选择
e.emp_name,电子邮件,电子邮件
从
员工e
LIMIT 10;
为了选择从第 11条记录开始的下10行,您可以编写:
选择
e.emp_name,电子邮件,电子邮件
从
员工e
LIMIT 10,10;
列太多
始终查看查询:带有怀疑的SELECT *。该查询返回所有列,您可能只需要其中一些。检索所有列的最大缺点是,它通过阻碍索引的使用来阻止优化,从而导致服务器需要过多的I / O,内存和CPU资源。
理解这样的通用查询检索所有列可能是浪费的。有人说它们很有用,因为它使开发人员可以在多个地方使用相同的代码。如果所涉及的成本被限制在考虑范围之内,那很好。在这种情况下,有时缓存检索到的数据会有所帮助。但是要小心,利用性能是一项时尚的工作,而这种奢侈可能没有性能的地方。
经验法则是避免此类通用查询,或将获取的列数保持尽可能少。
数据分析过多
查询返回的结果很好,但是有时这些查询的编写方式使得在处理查询时,需要在生成结果之前检查过多的数据。因此,在MySQL中,您必须根据以下成本指标进行衡量:
- 执行时间处理时间
- 行检查
- 检查的列
您可以从这些指标中大致估算出查询成本。这些反映了MySQL内部处理查询的数据访问量以及查询运行的速度。由于这些指标记录在慢查询日志中,因此最好调查并查找分析过多数据以返回结果的查询。MySQL数据库在慢速查询日志中注册所有超过给定执行时间的查询。这是查找慢查询并找出慢查询频率的理想场所。
慢查询日志通常位于/var/log/mysql/mysql-slow.log
注意,可能必须如下设置并启用mysqld.cnf配置文件中的慢速查询日志记录。
#slow_query_log = 1
#slow_query_log_file = /var/log/mysql/mysql-slow.log
#long_query_time = 2
在MySQL 5之前和之前,存在严重的局限性,尤其是缺乏对细粒度日志记录的支持。仅有喘息的地方是使用启用了日志记录的补丁。但是,该功能已作为其核心功能的一部分纳入MySQL 5.1和更高版本的服务器中。
执行时间过多的查询并不一定意味着它们是错误的查询。慢查询日志只是提供了检查查询性能并尽可能提高查询性能的机会。
重组查询
当您有机会重组有问题的查询时,您的主要目标应该是找到替代解决方案以实现我们想要的效果。您可以在处理过程中牢记MySQL服务器的内部影响,将查询转换为等效形式。
查询设计的一个决定是,我们是否应该偏向一个复杂的查询而不是几个简单的查询,反之亦然。数据库设计的常规方法是用更少的查询来完成尽可能多的工作。原因是就建立数据库连接而言,一个大/复杂查询更具成本效益。降低成本以支持复杂查询的优势是网络使用率,查询处理/优化和资源利用率。但是这种传统方法在MySQL中并不适合。MySQL旨在快速处理数据库连接和断开连接。因此,建立连接,触发许多更简单的查询并关闭连接似乎更有效。通过一个以上的简单查询代替一个大的复杂查询来检索数据更为有效。
结论
这些是查询优化的一些快捷方式。仅仅知道SQL语法就能够创建查询以检索所需结果的查询是不够的。了解看起来很简单的查询背后的情况对于编写这样的查询至关重要,该查询不仅可以检索所需的内容,而且还可以从所有内容开始就对优化技术进行注入。查询处理的幕后发生为理解查询性能提供了重要线索,而这种知识是进入查询优化领域之前必不可少的。