当前位置: 首页 > 知识库问答 >
问题:

主键的优化不起作用

谷梁凌
2023-03-14

如果您在一个表上的非空列上使用计数,而没有任何where部分,则优化器只需返回该表中的行数。

如果您要求对一个唯一的非空列(如主键)进行非重复计数,答案应该是相同的,但是这次mariadb代替了。

如果您在其他表上留下了联接,但仍然没有 where 部分,则结果仍应为该表中的行数。

Mariadb 不使用千次优化是有原因的吗?是否存在未过滤主键的 DISTINCT 计数可以给出任何其他结果,然后该 tabel 中的行数?

案例:

CREATE TABLE products (
    our_article_id varchar(50) CHARACTER SET utf8 NOT NULL,
    ...,
    PRIMARY KEY(our_article_id)
);

CREATE TABLE product_article_id (
    article_id varchar(255) COLLATE utf8_bin NOT NULL,
    our_article_id varchar(50) CHARACTER SET utf8 NOT NULL,
    ...
    PRIMARY KEY(article_id),
    INDEX(our_article_id)
);

计数查询,第一,基本计数

DESCRIBE SELECT COUNT(our_article_id) FROM products;         
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|    1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+------+-------------+-------+------+---------------+------+---------+------+------+------------------------------+

主键上的第二个DISTINCT

DESCRIBE SELECT COUNT(DISTINCT our_article_id) FROM products;
+------+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+
| id   | select_type | table    | type  | possible_keys | key     | key_len | ref  | rows   | Extra       |
+------+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+
|    1 | SIMPLE      | products | index | NULL          | PRIMARY | 152     | NULL | 225089 | Using index |
+------+-------------+----------+-------+---------------+---------+---------+------+--------+-------------+

第 3 个,主键上的不同,以及一个没有 WHERE 部分的左连接

DESCRIBE SELECT COUNT(DISTINCT our_article_id) FROM products LEFT JOIN product_article_id USING (our_article_id);
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+
| id   | select_type | table              | type  | possible_keys | key     | key_len | ref                              | rows   | Extra       |
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+
|    1 | SIMPLE      | products           | index | NULL          | PRIMARY | 152     | NULL                             | 225089 | Using index |
|    1 | SIMPLE      | product_article_id | ref   | PRIMARY       | PRIMARY | 152     | testseek.products.our_article_id |  12579 | Using index |
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+

共有1个答案

郎磊
2023-03-14

" mariadb没有使用thous优化有什么原因吗?"-MySQL/Maria db中有数不清的优化缺失;那个不见了。让我们看看历史。

MySQL在大约20年前开始作为一个精简的数据库引擎。它专注于大多数人需要的特性,同时最小化开销。这意味着许多罕见的优化没有出现在早期版本中,只有当它们看起来足够重要时,才会随着时间的推移而增加。

主键为例。它被定义为唯一。这是B树组织。而且,对于InnoDB,它也被定义为集群。其他供应商允许各种组合聚类、非 BTree 索引等。MySQL认为这些限制对于“大多数”人来说“足够好”。

多年来,“最严重的”遗漏已逐渐得到修复。交易可能是最大和最重要的。它于2001年(?)到达,随着8.0的推出,MyISAM将于今年(2016年)被移除。

4.1(2002?)看到了子查询。在此之前,创建一个tmp表已经“足够好了”。现在(8.0)子查询被CTE超越了,它涵盖了tmp表和子查询都无法有效完成的一些事情。

MySQL 5.6和5.7以及MariaDB 10.x中已经进行了大量的优化;您可能没有使用过其中的几个。该产品进入“收益递减”。如果它减慢优化器的速度以检查接下来的一千个极其罕见的优化,它将破坏其“精益和平均”的遗产。

与此同时,像我这样的人花了很多时间说“MySQL / MariaDB没有这个;这是解决方法“。在您的情况下,它是较短的计数(*)。由于有一个干净的解决方法,因此您的建议可能需要十年才能实施。可以向 bugs.mysql.com 提交错误报告,也可以 mariadb.com 来建议优化。

另一个几乎不需要的例子是< code>INDEX(a ASC,b DESC)作为优化a ASC,b DESC的< code >顺序的一种方式。这是8.0版附带的。但我怀疑5000个查询中是否有一个以上真的需要。(我看到了很多查询。)我认为,它的罕见性是它花了20年时间才得以实施的原因。缺乏一个干净的解决方案是它没有再花十年时间的原因。

 类似资料:
  • 我有一个用户表,ID列作为主键。我有这个功能在控制器: 此函数不回显任何内容。如果我从$id更改为$name,如下所示:

  • 我正在使用用户密钥作为用户表中的主键 它总是显示这样的错误

  • 这是我的模型: 以下是表格: 这些实体是: 我得库: org.hibernate:hibernate-core:jar:4.2.17.final:compile org.hibernate.common:hibernate-commons-annotations:jar:4.0.2.final:compile org.hibernate.javax.persistence:hibernate-jp

  • 问题内容: 我在库存表上建立类型,通过6种不同的因素跟踪库存。我正在使用一个类似于此查询的查询: 该表具有一个唯一键(productid,factor1,factor2,factor3,factor4,factor5,factor6,serial_number)。由于某种原因,它不是拿起钥匙而是只拨而不是拨。谁能提供一个解释为什么?我想念什么? 这是表create语句: 更深入: 该表的目的是保存

  • 我有两个表:和。 在类中,我声明了字段,如下所示: 当我获得列表时,也被加载(我看到了许多单独的SELECT查询)。但我希望是惰性加载的,而不是与一起提取的。 对于其他表,如果引用的列是主键,则结果与预期一样(使用懒惰加载)。在我的示例中,不是表的主键,并且Hibernate不使用惰性加载。 你能告诉我怎样实现那个目标吗?

  • 表模式 用户模型 下面是我在Laravel 5中的代码 错误消息 SQLSTATE[42S22]:未找到列:“where子句”中的1054未知列“user.id”(SQL:select*fromwhere=1限制1)