2015-05-09 67 views
0

我对如何优化我的SQL查询有点困惑。我有一个中间复杂的查询,一些连接每秒钟运行一百到几百次(SSD上有两个表,一个RAM在RAM中,有四个JOIN)如何在高负载下优化mysql查询的性能?

如何最小化执行的开销?有没有什么方法可以预编译查询,以便MySQL不需要每次都分析,优化和编译查询?

我知道我可以使用预准备语句来预编译一个查询,然后在同一个会话中执行多次查询。但如果您有多个会话并且每个会话只有一个查询,该怎么办?准备好的语句是否在不同的会话中被缓存?我不这么认为。

然后我认为存储过程是最好的方法,因为它们被预编译。现在我读到这个假设是完全错误的,他们事实上是而不是预编译。

是否可以在MySQL中共享客户端会话在以下会话继承的第一个会话中使用预准备语句?

最后一个想法是编写一个多线程套接字服务器来像MySQL客户端代理一样工作。但是这对我来说似乎有点夸张。 ;-)

我使用PHP作为Apache2模块。是否有机会将MySQL会话“存储”在共享内存中,以便下面的HTTP请求可以使用现有的MySQL会话而不是启动一个新的会话?这样我可以在不同的HTTP请求中使用预准备语句?

+1

“运行hundret每秒一千次” - 照顾扩大。不是通常的网络应用程序 –

+1

您似乎确实专注于跨会话共享/缓存已编译的查询,但如果您的瓶颈是由于编译而非I/O造成的,则这只会提高性能。索引和缓存不在这里?为什么您的查询每秒运行1000次?我认为我们需要更多地了解您的实际问题以提供帮助。 – Phil

+0

使用memcache。它总是拯救你的生命。 – hakiko

回答

1

问:有没有办法“重用”MySQL连接,以便后续请求可以使用现有连接?

- 答:是的。您可以使用连接池执行。这是一个熟悉的Java模式,有几个可用的实现。

对于PHP中的连接池实现,您可以使用PHP扩展mysqldnd-ms

参考:http://php.net/manual/en/mysqlnd-ms.pooling.php

注:我没有这个PHP扩展的亲身经历。


一些你问的其他问题......

问:我怎样才能最大限度地减少执行的开销?有没有什么方法可以预编译查询,以便mysql不需要每次都分析,优化和编译查询?

- 答:在MySQL 5.6中,您可以使用服务器端准备语句。预准备语句的执行计划会缓存在会话中,因此对相同SQL语句的重复调用可以重新使用先前准备好的执行计划。 (此功能在5.6以前的MySQL版本中不可用)

减少“连接搅动**”会减少MySQL开销。连接和断开数据库服务器是服务器必须执行的工作。测试和比较性能在一个进程中,打开一个连接并重复一些工作(重复执行一个简单的语句,如SELECT NOW(),然后断开连接。在另一个进程中,运行与SELECT相同的重复执行,但连接并断开连接每次执行

问:?可以在不同的会议上被缓存准备好的发言

答:否。语句缓存在 语句 会话级别。

问:是否可以在mysql中共享客户端会话?在以下会话继承的第一个会话中使用预准备语句?

答:号,你会得到这样的事情发生的唯一方法是从数据库断开连接,该会话的句柄传递给后续的客户端请求的连接。我们通过实施连接池来实现。


+0

非常感谢,这正是我想知道的。但是,我不明白为什么服务器端预处理语句会在全局范围内缓存在会话中,因此只有结合持久连接才能获得真正的优势。无论如何,这听起来很有希望,以及连接池。再次感谢! – McJoey

0

我会说这样做的最佳做法之一是避免基于O(n)时间的查询和函数。为了能够在高负荷数据下正常工作,所有查询必须在O(1)额外的时间内完成。实际上这意味着什么,无论您提取多少数据,查询总是需要相同的时间。 (线性方程)

我的意思是,如果您将IDS存储在$_SESSION var中,那么您可以稍后在需要将查询从O(n)到O(1)的时间减少时使用它。

+0

虽然我同意你说的大部分内容,但是让所有查询O(1)说起来容易做起来难,除非你正在向串行日志插入查询,否则通常是不可能的。使用索引SELECT可以获得O(log(n)),其中数据的增加会影响速度,但是随着数据增长,您很少可以完全停止查询减速。 – Phil

+0

我完全同意你在说什么。事实上,我知道要达到这个目标有多困难。但是,如果我们正在处理如此大量的数据,我们可以尝试寻找更具可扩展性的解决方案。如NoSQL。我会说,基于文档的NoSQL系统在这种情况下可以工作@ Phil_1984_ –

+0

O(1)不幸的是我们不可能:-)但是查询不是时间敏感的,我可以修改时间间隔,甚至可以删除查询当资源耗尽时。 – McJoey

0

如果你陷入读取困境,奴隶可以允许几乎无限的阅读缩放。

其他问题: - 配料的INSERT语句中有很大帮助。 InnoDB在并发访问方面更好。 - 跨国延迟可能会导致存储过程(以及其他技术)可以缓解的延迟。 - 一般来说,您所要求的开销不如查询优化重要。 - 由于延迟较少,SP有时可以提供帮助。 - * Nix比Windows好。 - 太多“同时”连接可能会适得其反。 - PHP会话不太可能有用。