如果在一个表上使用非空列的计数,而没有任何where-parts,则optimaizer只返回该表中的行数。
如果你要求UNIQE非空列上的DISTINCT计数,比如PRIMARY KEY,答案应该是相同的,但是这次mariadb会进行计算。
如果你在其他表上保持连接,但仍然没有where-parts,那么结果应该仍然是该表中的行数。
mariadb是否有理由不使用优化?有没有未经过滤的主键的DISTINCT计数,是否可以给出任何其他结果然后该表格中的行数?
情况下:
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)
);
计算查询,第1次,基本计数
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,关于PRIMARY KEY的DISTINCT,以及没有WHERE-parts的LEFT JOIN
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 |
+------+-------------+--------------------+-------+---------------+---------+---------+----------------------------------+--------+-------------+
答案 0 :(得分:2)
" mariadb是否有理由不使用优化措施?" - MySQL / MariaDB中存在大量缺失的优化;那个失踪了。让我们来看看历史。
MySQL大约20年前开始作为精简和平均数据库引擎。它专注于大多数人需要的功能,同时最大限度地减少开销。这意味着许多罕见的优化不在早期版本中,并且只有在它们看起来足够重要时才会被添加。
以PRIMARY KEY
为例。它被定义为UNIQUE。它是BTree组织的。而且,使用InnoDB,它也被定义为Clustered。其他供应商允许各种组合聚类,非BTree索引等.MySQL认为这些限制足够好"对于"大多数"人
多年来,“最糟糕的”'遗漏已逐渐修复。交易可能是最大和最重要的。它于2001年(?)到达,MyISAM将于今年(2016年)以8.0的出现被删除。
4.1(2002?)看到了子查询。在此之前,创建一个tmp表就足够了#34;。现在(8.0)子查询由CTE提升,其中包括tmp表和子查询都无法有效执行的一些事情。
对MySQL 5.6和5.7以及MariaDB 10.x进行了大量优化;你可能没有使用过多个。产品进入"收益递减"。它会损害它的精益和意味着"遗产,如果它减慢了优化器,以检查下一千个非常罕见的优化。
与此同时,像我这样的人花了很多时间说" MySQL / MariaDB没有那个;这是解决方法"。它是您案件中较短的COUNT(*)
。由于有一个干净的解决方法,可能还需要另外十年才能实施您的建议。可以使用bugs.mysql.com或mariadb.com提交错误报告以建议优化。
另一个,几乎从不需要的案例,INDEX(a ASC, b DESC)
是优化ORDER BY a ASC, b DESC
的一种方式。这是8.0。但我怀疑5000个中是否有多个查询确实需要它。 (我已经看到了很多疑问。)我认为它的罕见性是为什么花了二十年才实现它。缺乏一个干净的解决方法是为什么它不需要再过十年。