Mysql 查询在第一次运行时花费了很长时间

Mysql 查询在第一次运行时花费了很长时间,mysql,sql,database,performance,Mysql,Sql,Database,Performance,我的网站在访问高峰期出现严重问题。在做了很多故障排除之后,我发现问题出在数据库上 我有一个主查询,它在检索数据表的索引上运行 在繁忙的一天,站点第一次加载需要30到45秒,但每次加载后,它都会非常快地加载大约5分钟,然后再次减速,最终站点会因为负载过大而停机 我直接在数据库上测试了查询,它的性能完全相同 这会更多地与查询或MySQL配置有关吗 它工作得非常好,返回的结果很小,但是在繁忙的一天,当列表非常大时,它的速度会减慢,并杀死网站 编辑: 谢谢你的建议 我稍微修改了查询,并对数据库做了一些修

我的网站在访问高峰期出现严重问题。在做了很多故障排除之后,我发现问题出在数据库上

我有一个主查询,它在检索数据表的索引上运行

在繁忙的一天,站点第一次加载需要30到45秒,但每次加载后,它都会非常快地加载大约5分钟,然后再次减速,最终站点会因为负载过大而停机

我直接在数据库上测试了查询,它的性能完全相同

这会更多地与查询或MySQL配置有关吗

它工作得非常好,返回的结果很小,但是在繁忙的一天,当列表非常大时,它的速度会减慢,并杀死网站

编辑:

谢谢你的建议

我稍微修改了查询,并对数据库做了一些修改,因为有些名称不合理

在您提出所有建议之后,我还修改了查询,以删除通配符搜索以及对不再需要的表的一些冗余请求

以下是查询本身:

SELECT g.id, g.`name`, g.scores, g.sportFK, g.`desc`, g.`date`, s.id AS streamid
       FROM games AS g
       LEFT JOIN streams AS s ON s.gameFK = g.id
             WHERE
                  (g.date >= '" . $date . "' AND g.date <= '" . $newdate . "') 
                  AND g.sportFK IN (" .  $sportfk . ") 
                  ORDER BY g.date ASC"
这是针对“STREAMS”表的

STREAMS TABLE:

SIZE: 80MB
ROWS: 135296
TYPE: MyISAM


编辑:马丁,谢谢你对这篇文章的观点。这个数据库确实是从另一个源以相当固定的间隔填充的,因此会发生持续的读写操作。我必须对此做更多的研究。

可能发生的情况是,第一次运行查询时额外的时间用于编译查询和开发执行计划。这会缓存一段时间,然后再次发生


解决方案是将查询放入存储过程。

如果查询执行多次,数据库通常会在引擎盖下进行缓存以提高性能。 如果您想提高性能,您可能希望获得一个解释计划,并改进数据库结构或查询结构

为了改进数据库,请检查解释计划,确保没有像全文扫描这样昂贵的操作。 例如,您可能希望看到在g.name和连接列上添加索引的影响。 尝试添加索引,看看成本的提高。
在添加索引时要小心,因为写入速度慢,并且会增加数据库大小。

好吧,对于每个数据库开发人员来说,这个查询的性能都很糟糕:-)

首先由于查询编译和执行计划计算,可以延长时间。您可以使用
EXPLAIN
查看它

由于该行为在5分钟内重复出现,我认为索引本身或缺少索引应该存在问题

您应该指定在网站加载中是只有读取,还是同时读取(使用您的查询)和写入

索引重新计算一旦您还将执行写入操作,就开始发挥作用。另一个可能的问题是锁定。假设有人每5分钟写入一次数据,查询就非常复杂,因此它应该为写入事务锁定表,而您的读取将等待提交/回滚

请注意,这个查询非常复杂,而且永远不会很快——我的意思是非常快

  • 使用索引的另一个表上存在计数
  • 一个连接到另一个具有大条件的表-连接本身是一个慢点
  • 两个where子句=>两个索引
  • 使用另一个索引进行排序
您可以看到有两个索引。写操作只是锁定表和索引并更新它们,您有5个。内部计数也不好


如果您需要非常好的性能或定义经典的方法,我会推荐更好的DB或域设计:是经常读还是经常写?然后重新设计它。

您的表上有合适的索引吗?您不需要从表中获取所有(*)数据吗?当参数不是模式时,为什么要使用
LIKE
prod_name
cat_name
是否可以包含通配符?此查询可能存在的瓶颈是“LIKE”、“JOIN”和sub“SELECT”-如果可能,请尽量避免这些瓶颈。您还应向我们提供explain的输出。您需要向我们显示表和索引定义,以及每个表的行计数。也许您的表定义不好。可能索引没有正确创建。也许你在你认为你有的专栏上没有索引。如果看不到表和索引定义,我们无法判断。我们还需要行计数,因为这会极大地影响查询优化。如果你知道如何做一个
解释
或获得一个执行计划,那么把结果也放在问题中。Martin感谢你在写作中提出的观点。这个数据库确实是从另一个源以相当固定的间隔填充的,因此会发生持续的读写操作。我将不得不对此做更多的研究。在当前状态下,您的操作是否得到了改进?我们在表锁定方面遇到了许多问题,导致我们克隆表。我的意思是,我们已经使用了用例,定义了哪些操作阻塞了另一个操作,并将数据划分为单独的表。现在,当一个线程/客户机写入数据时,第二个线程/客户机根本不受影响。确切地说,我们的情况如下:我们得到了某种主要的聚合。可以使用REST将其部署到服务器,服务器可以对其进行处理。我们在这些主聚合级别上划分表,因此当有人部署一个聚合时,它不会在服务器端阻止另一个聚合的处理,因为它们是不同的表。我们已经学到了很多关于数据库的知识。它鼓励我开始阅读NoSQL。原因是RDBMS,在我们的例子中是MS SQL,做了许多不可预料的事情,或是很难学习或判断的事情。有时它会锁上整张桌子
STREAMS TABLE:

SIZE: 80MB
ROWS: 135296
TYPE: MyISAM