Mysql 分区修剪不适用于我的子查询
Mysql Partition pruning not working on my subquery
explain
SELECT
ip_src,
(SELECT country FROM ip_location WHERE ip_start between (134744072-500000) and (134744072) and ip_end > 134744072) country_src,
ip_dst
FROM
event e
WHERE
long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1
partition pruning working
explain
SELECT
ip_src,
(SELECT country FROM ip_location WHERE ip_start between (ip_src-500000) and (ip_src) and ip_end > ip_src) country_src,
ip_dst
FROM
event e
WHERE
long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1
partition pruning not working
我有 2 个查询,
ip_src 值为 134744072。
我的 Ip_location table 在 ip_start 列上按范围分区。
当我 运行 第一次查询时,它完成了分区 p运行ing,但在第二次查询中它访问了所有分区。
任何人请给我线索,我环顾四周但不知道发生了什么事,先谢谢你:)
决定执行计划(包括它不需要的分区)的优化器在从 table 读取实际数据之前运行。
您的第一个查询将您的子查询限制在常数值 134744072-500000
和 134744072
之间的 ip_start
的特定范围内,因此很清楚数据位于哪个分区。(顺便说一句.: 你必须确保子查询 returns 最多一行,否则会导致错误。
对于你的第二个查询,优化器在开始之前无法知道所需的范围。这将取决于它在读取 event
table 时找到的数据。这就是为什么这个查询的 select_type
是一个 dependent subquery
,而对于第一个查询,它是一个 subquery
(所以一个固定的结果集独立于 event
table).所以优化器还不能排除一个分区,所以它会列出所有分区。执行查询时,它将读取第一行,现在知道 ip_src
的值为 134744072
,因此 ip_start
范围和数据所在的分区,以及所以 MySQL 现在将在正确的分区中查找它。
这两个查询实际上只会从那个分区读取,但是对于第一个,MySQL 知道在它开始之前,对于第二个,它不知道。
最后一个警告:您似乎正在尝试使用分区来加快查询速度。这不是分区的用途!为此使用索引。对于 limit 1
,它不会有什么不同,但是如果你查询更多的行,每个分区将像一个独立的 table(基本上是这样),所以不要在 1 个索引中查找数据(较大的table,但是当你有索引时,大小基本上无关紧要),MySQL必须在30、40个不同的分区(=tables)中查找数据,所有有自己的索引、文件和结构。这通常比不使用分区更慢(而且几乎永远不会更快)。 600,000 行可能已经足以看到至少一个小的影响,所以在没有分区的情况下进行测试。
explain
SELECT
ip_src,
(SELECT country FROM ip_location WHERE ip_start between (134744072-500000) and (134744072) and ip_end > 134744072) country_src,
ip_dst
FROM
event e
WHERE
long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1
partition pruning working
explain
SELECT
ip_src,
(SELECT country FROM ip_location WHERE ip_start between (ip_src-500000) and (ip_src) and ip_end > ip_src) country_src,
ip_dst
FROM
event e
WHERE
long_date BETWEEN '2016-03-25 00:00:00' AND '2016-03-25 23:59:59'
LIMIT 1
partition pruning not working
我有 2 个查询, ip_src 值为 134744072。
我的 Ip_location table 在 ip_start 列上按范围分区。 当我 运行 第一次查询时,它完成了分区 p运行ing,但在第二次查询中它访问了所有分区。
任何人请给我线索,我环顾四周但不知道发生了什么事,先谢谢你:)
决定执行计划(包括它不需要的分区)的优化器在从 table 读取实际数据之前运行。
您的第一个查询将您的子查询限制在常数值 134744072-500000
和 134744072
之间的 ip_start
的特定范围内,因此很清楚数据位于哪个分区。(顺便说一句.: 你必须确保子查询 returns 最多一行,否则会导致错误。
对于你的第二个查询,优化器在开始之前无法知道所需的范围。这将取决于它在读取 event
table 时找到的数据。这就是为什么这个查询的 select_type
是一个 dependent subquery
,而对于第一个查询,它是一个 subquery
(所以一个固定的结果集独立于 event
table).所以优化器还不能排除一个分区,所以它会列出所有分区。执行查询时,它将读取第一行,现在知道 ip_src
的值为 134744072
,因此 ip_start
范围和数据所在的分区,以及所以 MySQL 现在将在正确的分区中查找它。
这两个查询实际上只会从那个分区读取,但是对于第一个,MySQL 知道在它开始之前,对于第二个,它不知道。
最后一个警告:您似乎正在尝试使用分区来加快查询速度。这不是分区的用途!为此使用索引。对于 limit 1
,它不会有什么不同,但是如果你查询更多的行,每个分区将像一个独立的 table(基本上是这样),所以不要在 1 个索引中查找数据(较大的table,但是当你有索引时,大小基本上无关紧要),MySQL必须在30、40个不同的分区(=tables)中查找数据,所有有自己的索引、文件和结构。这通常比不使用分区更慢(而且几乎永远不会更快)。 600,000 行可能已经足以看到至少一个小的影响,所以在没有分区的情况下进行测试。