Mysql ASC与DESC之间的TokuDB分拣时间不同

Mysql ASC与DESC之间的TokuDB分拣时间不同,mysql,mariadb,tokudb,Mysql,Mariadb,Tokudb,这是从Tokutek下载的MariaDB+Tokudb7.1社区。请接受我的无知,如果这是正常的行为,但我有一个关于排序结果的问题。我在两个排序方向(升序和降序)之间的排序中遇到了巨大的时间差: SELECT sql_no_cache id, createts, deleted FROM sort_test WHERE createts > '2000098' ORDER BY createts asc +---------+----------+---------+ | id

这是从Tokutek下载的MariaDB+Tokudb7.1社区。请接受我的无知,如果这是正常的行为,但我有一个关于排序结果的问题。我在两个排序方向(升序和降序)之间的排序中遇到了巨大的时间差:

SELECT sql_no_cache id, createts, deleted
FROM sort_test
WHERE createts > '2000098'
ORDER BY createts asc

+---------+----------+---------+
| id      | createts | deleted |
+---------+----------+---------+
| 1999999 |  2000099 |    NULL |
| 2000000 |  2000100 |    NULL |
+---------+----------+---------+
2 rows in set (0.00 sec)

SELECT sql_no_cache id, createts, deleted
FROM sort_test
WHERE createts > '2000098'
ORDER BY createts desc

+---------+----------+---------+
| id      | createts | deleted |
+---------+----------+---------+
| 2000000 |  2000100 |    NULL |
| 1999999 |  2000099 |    NULL |
+---------+----------+---------+
2 rows in set (0.55 sec)
下面我展示我的简化测试用例。这是表格:

CREATE TABLE `sort_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `createts` int(11) DEFAULT NULL,
  `deleted` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_createts` (`createts`)
) ENGINE=TokuDB
在这里,我使用以下步骤用200万行填充表格:

delimiter ;;

drop procedure if exists sort_test_populate;;

create procedure sort_test_populate()
begin
DECLARE int_val INT DEFAULT 1;
myloop : LOOP
  if (int_val > 2000000) THEN
    LEAVE myloop;
  end if;
  insert into sort_test (id, createts) values (int_val, int_val+100);
  set int_val = int_val +1;
end loop;
end;;

call sort_test_populate();;
Query OK, 1 row affected (28 min 2.80 sec)
下面是我的测试查询:

SELECT sql_no_cache id, createts, deleted
FROM sort_test
WHERE createts > '2000098'
ORDER BY createts asc

2 rows in set (0.00 sec)

SELECT sql_no_cache id, createts, deleted
FROM sort_test
WHERE createts > '2000098'
ORDER BY createts desc

2 rows in set (0.55 sec)
这是“解释扩展”结果,两个查询的结果相同:

+------+-------------+-----------+-------+---------------+--------------+---------+------+------+----------+-------------+
| id   | select_type | table     | type  | possible_keys | key          | key_len | ref  | rows | filtered | Extra       |
+------+-------------+-----------+-------+---------------+--------------+---------+------+------+----------+-------------+
|    1 | SIMPLE      | sort_test | range | idx_createts  | idx_createts | 5       | NULL |    2 |   100.00 | Using where |
+------+-------------+-----------+-------+---------------+--------------+---------+------+------+----------+-------------+

请注意,这不是我正在处理的确切数据,这太多了,无法包含在这里。我只是想创建一些测试数据来演示这个问题。我的问题是-为什么会这样,以及如何使降序查询更快?

这是一个已知的索引条件下推(ICP)错误。解决方法是通过全局或在执行此查询的会话中设置optimizer_开关来禁用ICP

mysql> SET optimizer_switch='index_condition_pushdown=off';

(完全披露,我是Tokutek的员工,TokuDB的制造商)

范围
WHERE createts<103
的性能如何?如果我使用
WHERE createts<103
,那么ASC和DESC排序的性能都非常好。我怀疑您在索引中遇到了节点边界问题,TokuDB必须访问两个节点才能检索结果。您尝试过MySQL版本吗我刚从Tokutek安装了TokuDB 7.1的mysql版本,没有出现问题。对于ASC和DESC排序,我得到了同样好的测试查询时间(0.00秒)。此外,如果在任一版本(mysql或mariadb)中使用myisam表,则根本不会出现问题。是的,该解决方案修复了我的测试用例查询以及我遇到相同问题的实际查询。