我是MySQL世界的新手。
当我读到关于MySQL范围优化的文章时,提出了一些与多部分指标相关的问题。
(http://jorgenloland.blogspot.com/2011/08/mysql-range-access-method-explained.html)
问题1:
单次和连续间隔的含义是什么?
问题2:
与多部分指数和酮有关
表结构
Create table orders(
customer_id int,
value int,
name varchar(20),
primary key(customer_id,value)
) ;a)
mysql> explain select * from orders where customer_id <= 2 and value = 1;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | orders | NULL | range | PRIMARY | PRIMARY | 8 | NULL | 4 | 25.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+b)
mysql> explain select * from orders where customer_id < 2 and value = 1;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | orders | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 4 | 25.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+为什么解释语句(A)显示keylen为8,而(B)表示keylen为4?
发布于 2018-11-23 20:05:31
EXPLAIN的输出中存在许多缺陷。这对我来说是新的。
例如“覆盖”索引、范围、ORDER BY等等,key_length都表示得很差。而且,NULLable列的长度是常量,而不是1或2,这取决于架构。
“使用临时的,使用的文件”通常位于第一行,即使在进行排序时不是这样。
GROUP BY x ORDER BY y可能需要两种类型;没有任何线索。
使用EXPLAIN FORMAT=JSON SELECT ...获取更多信息,有时接近所有可用信息。
回到具体的例子。
一个更好的索引是这个顺序:(value, customer_id)。为了有效地使用索引的两列,col=constant中涉及的列应该放在第一位。
一种猜测是有一个相对较新的优化。MySQL/MariaDB的哪个版本(S)显示这种不一致的key_len?
正如约尔根在博客中所说:
在优化器代码中,应该以同样的方式处理<,>和声音之间的差异,因为这些条件都是奇怪的。一种理论是,优化器认为执行此查询的两种方法几乎一样好,因此有时会选择一个好的计划,而另一些时候则会因为索引统计量的微小差异而选择次优计划。但是,如果您能够始终如一地重现此问题,则可能需要在bugs.mysql.com上提交一个bug。
也就是说,请提供一个完整的测试用例--创建、插入、解释等等--在至少一个版本的MySQL中始终如一地演示这个问题(越新越好)。
在他的最新博客中找到了答案:
但这留下了一个问题:为什么key_length=10用于查询的中间版本?原因是,虽然值键部分不能用于设置范围,但它用于确定第一个范围的起始点(此查询中只有一个范围--尝试优化器跟踪并自己查看),而且在读取值< 500和customer_id=7的索引行时没有任何用处。
谢谢你的提问,我学到了一些东西。
至于你的问题1:
相反,条件key_part3 = 'abc‘不定义单个间隔,也不能由范围访问方法使用。
再加上WHERE key_part3 = 'abc' (没有任何其他条款)和INDEX(kp1, kp2, key_part3).它是说,在基于(kp1, kp2, key_part3)的有序列表中,可能有几个区域(而不是一个“单一范围”),其中发现了abc。
最好到索引中的一个位置,然后扫描,直到没有更多的相关行。但在这种情况下,您需要查看索引中的几个点。这种讨论导致了这样做的“新”能力(某种程度上)。
底线是..。正如在我的索引食谱中所讨论的,最好的索引是从列(S)开始的,该列是用常数(S)来测试的。有时,优化器可以在列没有最优排序的情况下使用一些索引。
https://dba.stackexchange.com/questions/223301
复制相似问题