联邦表上没有 WHERE 子句的慢速 SELECT ... LIMIT
Posted
技术标签:
【中文标题】联邦表上没有 WHERE 子句的慢速 SELECT ... LIMIT【英文标题】:Slow SELECT ... LIMIT without WHERE clause on federated table 【发布时间】:2015-04-28 15:03:49 【问题描述】:我遇到了一个关于联合表引擎的问题:
我创建了一个联合表,指向一个合理的大型远程表(大约 800.000 行,行大小 211 字节,MyISAM)。
发送以下查询时:
SELECT * FROM TABLE LIMIT 0,30
查询总是需要 9 秒才能完成。
尝试:
SELECT * FROM TABLE WHERE primaryKey = 1234
像往常一样快(
我尝试在几个数据库服务器上尝试联合表,结果总是相同。现在我的问题是:幕后是否发生了我不知道的事情? mysql 是否在没有 WHERE 子句的情况下获取整个索引?是否需要一些内部排序?
无论如何,在我看来,提供数据的远程数据库服务器应该毫不拖延地处理这个问题,不是吗?
Mysql version: 5.5.31
【问题讨论】:
对于第一个查询,MySQL 获取所有 800 000 行,然后从内部结果指针的第 0 个偏移量开始获取其中的 30 行,并丢弃其余行。由于它是 MyISAM,它涉及大量的磁盘 I/O。 “帮助” MySQL 更快地做到这一点的一种方法是实现一个小作弊。你可以通过类似SELECT * FROM table WHERE id < 1000 LIMIT 0, 30
的方式来帮助它。现在,正如你已经看到的那样——我称之为作弊,因为你需要以某种方式帮助 MySQL 减少它搜索的数据集——PK 始终是理想的候选者。
【参考方案1】:
FEDERATED
有很多问题。它本质上是要求另一台机器一次发送一行。这会产生往返开销。
优化器不是很好,尤其是FEDERATED
,在“下推”操作到其他服务器。也就是说,它不会将可以由其他服务器完成的工作交给其他服务器,而是会询问记录,然后在服务器上执行启动查询的工作。
注意像 (FEDERATED,无法正确维护 QC,因此要么自动禁用它,要么您应该禁用它。 (我不知道是哪个。)
从表限制 0,30 中选择 *
这不会获取任何索引。它从“数据”中获取行。我会期望它获取 30 行(以 .MYD 中的第一个 30 行为准)然后退出。但是FEDERATED
可能比这更笨。
对于MyISAM
,PRIMARY KEY
与任何其他UNIQUE
键相同。
一种更深入地了解正在发生的事情的方法:
FLUSH STATUS;
SELECT * FROM TABLE LIMIT 0,30;
SHOW SESSION STATUS LIKE 'Handler%';
我希望看到一个或两个大约 30 的处理程序。但是,从你的“9 秒”来看,它可能会说大约 800000。如果“800000”,那么看起来FEDERATED
不能有效地做一些简单的事情作为你的LIMIT
。
【讨论】:
以上是关于联邦表上没有 WHERE 子句的慢速 SELECT ... LIMIT的主要内容,如果未能解决你的问题,请参考以下文章
Mysql InnoDB 视图变得缓慢并且不使用 Where 子句