对一个innodb来说,限制并发线程的主要目的是减少上下文切换导致的性能问题。
在有助于最大程度地减少线程之间的上下文切换的情况下,InnoDB可以使用多种技术来限制并发执行的操作系统线程的数量(从而限制在任何时间处理的请求的数量)。当InnoDB从用户会话接收到新请求时,如果同时执行的线程数处于预定义的限制内,则新请求将休眠一小段时间,然后再次尝试。睡眠后无法重新安排的请求被放入先进/先出队列,并最终得到处理。等待锁的线程不计入同时执行的线程数。

您可以通过设置配置参数innodb_thread_concurrency来限制并发线程数。一旦执行线程的数量达到此限制,其他线程就会休眠数微秒(由配置参数innodb_thread_sleep_delay设置),然后再放入队列。

以前,需要进行实验才能找到innodb_thread_sleep_delay的最佳值,并且该最佳值可能会根据工作负载而变化。在MySQL 5.6.3及更高版本中,您可以将配置选项innodb_adaptive_max_sleep_delay设置为允许innodb_thread_sleep_delay的最大值,然后InnoDB会根据当前线程调度活动自动向上或向下调整innodb_thread_sleep_delay。这种动态调整有助于线程调度机制在系统轻负载和接近满负荷运行时平稳运行。

在各种版本的MySQL和InnoDB中,innodb_thread_concurrency的默认值和并发线程数的隐含默认限制已更改。 innodb_thread_concurrency的默认值为0,因此默认情况下并发执行的线程数没有限制。

仅在限制并发线程数时,InnoDB才会使线程进入睡眠状态。当线程数没有限制时,所有线程都平等地争用调度。也就是说,如果innodb_thread_concurrency为0,则忽略innodb_thread_sleep_delay的值。

当线程数受到限制时(innodb_thread_concurrency> 0时),InnoDB通过允许在执行单个SQL语句期间发出的多个请求进入InnoDB而不遵守innodb_thread_concurrency设置的限制,从而减少了上下文切换开销。由于SQL语句(例如联接)可能在InnoDB中包含多个行操作,因此InnoDB分配了指定数量的“票证”,这些票证允许以最小的开销重复调度线程。(这里不太明白,为什么要ticket)

当新的SQL语句启动时,线程没有票证,并且必须遵守innodb_thread_concurrency。一旦线程有权进入InnoDB,便为其分配了许多票证,可用于随后进入InnoDB来执行行操作的票证。如果票证用完,线程将被逐出,并再次观察到innodb_thread_concurrency,这可能会将线程放回到等待线程的先进先出队列中。当线程再次有权进入InnoDB时,将再次分配票证。分配的票证数量由全局选项innodb_concurrency_tickets指定,默认情况下为5000。一旦锁可用,等待锁的线程将获得一张票证。

这些变量的正确值取决于您的环境和工作量。尝试各种不同的值,以确定哪种值适用于您的应用程序。在限制并发执行线程的数量之前,请查看可提高InnoDB在多核和多处理器计算机上的性能的配置选项,例如innodb_adaptive_hash_index。