我想知道一个 sql 命令。
我正在使用 MariaDB 10.0.33
表架构就像
+-----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| site_cd | varchar(20) | NO | PRI | NULL | |
| site_fair_cd | varchar(20) | NO | PRI | NULL | |
| detail_cnt | varchar(10) | NO | PRI | NULL | |
| name | varchar(50) | YES | | NULL | |
| little_title | varchar(50) | YES | | NULL | |
| info_text | varchar(255) | YES | | NULL | |
| yoyaku | varchar(20) | YES | | NULL | |
| charge | varchar(20) | YES | | NULL | |
| person | varchar(10) | YES | | NULL | |
| price | varchar(50) | YES | | NULL | |
| remainder | varchar(20) | YES | | NULL | |
| date | date | YES | | NULL | |
| time | varchar(50) | YES | | NULL | |
| start_sec | int(11) | YES | | NULL | |
| end_sec | int(11) | YES | | NULL | |
| url | varchar(200) | YES | | NULL | |
| crwl_date | datetime | YES | MUL | NULL | |
| regist | datetime | YES | | NULL | |
+-----------------+--------------+------+-----+---------+-------+
索引就像
+----------------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| table_name | 1 | crwl_date_index | 1 | crwl_date | A | 22237 | NULL | NULL | YES | BTREE | | |
SQL 是两种模式。
首先是如下。
EXPLAIN SELECT SQL_NO_CACHE DATE(crwl_date) AS date,count(*) AS cnt
FROM table_name
WHERE crwl_date >= '2018-03-20'
AND crwl_date < '2018-03-28'
GROUP BY DATE(crwl_date);
+------+-------------+----------------------------+-------+-----------------+-----------------+---------+------+-------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------------------------+-------+-----------------+-----------------+---------+------+-------+-----------------------------------------------------------+
| 1 | SIMPLE | table_name | range | crwl_date_index | crwl_date_index | 9 | NULL | 43958 | Using where; Using index; Using temporary; Using filesort |
+------+-------------+----------------------------+-------+-----------------+-----------------+---------+------+-------+-----------------------------------------------------------+
二是如下。
EXPLAIN SELECT SQL_NO_CACHE DATE(crwl_date) AS date,count(*) AS cnt
FROM table_name
WHERE crwl_date >= '2018-03-20'
AND crwl_date < '2018-03-28'
GROUP BY DATE(crwl_date)
ORDER BY NULL;
+------+-------------+----------------------------+-------+-----------------+-----------------+---------+------+-------+-------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------------------------+-------+-----------------+-----------------+---------+------+-------+-------------------------------------------+
| 1 | SIMPLE | table_name | range | crwl_date_index | crwl_date_index | 9 | NULL | 43958 | Using where; Using index; Using temporary |
+------+-------------+----------------------------+-------+-----------------+-----------------+---------+------+-------+-------------------------------------------+
第二个 SQL 包括“ORDER BY NULL”。所以“使用文件排序”消失了。
我不明白为什么会这样。请解释。
MySQL 和 MariaDB 有一个特性,当你
GROUP BY
没有时ORDER BY
,排序是使用 group by list 完成的。因此,您的第一个查询运行时就好像它是:当您显式添加
ORDER BY NULL
时,该功能将被禁用并且不ORDER BY
使用,因此不需要文件排序。这在MySQL
ORDER BY
优化中有解释:MariaDB 版本 10.1 和 10.2
ORDER BY
中也有一些关于 的改进,尽管我认为它们与您的情况无关。无论如何,最好升级到最新的稳定版本(当前为 10.2.13)。