2013-08-19 184 views
1

我的网站在访问高峰期间有严重问题。在做了很多故障排除之后,我发现问题在于数据库。第一次运行需要很长时间的查询

我有这个主要的查询运行索引检索数据表。

在繁忙的一天,该网站首次加载需要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" 

测试之后查询的首场演出仍然以33S运行,并且每一个后续执行是在0.04秒运行的sugegsts该网站上的效果会高峰时间到来时也是如此。

我也准备了从EXPLAIN请求的信息。

这是 '游戏' 表

Games Table

GAMES TABLE: 

SIZE: 6MB 
ROWS: 14841 
TYPE: INNODB 

这是 'STREAMS' 表

Streams Table

STREAMS TABLE: 

SIZE: 80MB 
ROWS: 135296 
TYPE: MyISAM 

编辑:马丁谢谢你提出一个关于写作的观点。这个数据库也会以相当规则的时间间隔从另一个源进行填充,所以会有不断的READ和WRITE操作。我将不得不对此做更多的研究。

+2

你的桌子上有适当的索引吗?你不需要不要从你的表中获取所有(*)数据? –

+3

为什么当参数不是模式时使用'LIKE'? 'prod_name'或'cat_name'是否可以包含通配符? – Barmar

+0

此查询的可能瓶颈是“LIKE”,“JOIN”和子“SELECT” - 尽量避免它们,如果可能的话 –

回答

1

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

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

+0

谢谢我一定会考虑使用存储过程,因为我没有使用它们的经验,所以我将不得不做一些阅读。 – Arturski

0

如果多次执行查询,数据库在引擎盖下进行缓存以提高性能是很正常的。 如果你想提高性能,你可能想得到一个解释计划,并改善你的数据库结构或改进你的查询结构。

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

1

那么,这个查询必须是恐怖的性能,每DB开发:-)

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

由于行为在5分钟内重复,所以我会说索引本身或缺少索引应该存在问题。

你应该指明只有网站负荷内读取或有随着写道:并发读(使用查询)。

索引重新计算一旦您还会执行写入操作,就会进入播放。另一个可能的问题是锁定。比方说,每5分钟有人写数据,查询就非常复杂,因此它应该锁定写入事务的表,并且读取会等到提交/回滚。

请注意,这个查询是非常复杂的,它永远不会很快 - 我的意思是非常快。

  • 有关于使用索引
  • 一个连接到具有大条件的另一表中的另一表计数 - 加入本身慢点
  • 2,其中使用另一种索引
  • 子句=>两个索引
  • 顺序

你会看到有几个索引。写操作只是锁定表和索引并更新它们,你有5个。内在计数也不好。

如果您需要非常好的性能或定义经典方法,我会推荐更好的数据库或域设计:经常被读取或写入?而不是重新设计它。

+0

马丁感谢你提出一个关于写作的观点。这个数据库也会以相当规则的时间间隔从另一个源进行填充,所以会有不断的READ和WRITE操作。我将不得不对此做更多的研究。在目前的状态下,你的意见得到了改善吗? – Arturski

+0

关于表锁的问题,我们遇到了很多麻烦,这导致我们到* clone *表。我的意思是我们已经使用了用例并定义了另一个操作块,并将数据划分为不同的表格。现在,当一个线程/客户端写入数据时,第二个完全不受影响。当我确切地说,我们的情况如下:我们得到某种主要聚合。它可以使用REST部署到服务器,服务器可以处理它。我们在这些主聚合级别上划分表,所以当有人部署一个聚合时,它不会阻止在服务器端处理另一个聚合,因为它们是不同的 –

+0

表。我们学到了很多关于数据库的知识。它鼓励我开始阅读NoSQL。原因在于,在我们的例子中,RDBMS,MS SQL做了许多难以理解或难以预测的事情或事情。例如。它有时会锁定整个表而不是索引本身,即使表包含正确的定义,有时也不会使用索引,因为它只是决定不使用它。或者像聚簇索引这样的术语是漫长冬夜的话题。很多事情在RDBMS中都有效。 –

相关问题