MariaDB DATETIME索引不使用来自_UNIXTIME()的中间

MariaDB DATETIME索引不使用来自_UNIXTIME()的中间,datetime,indexing,mariadb,Datetime,Indexing,Mariadb,我有一个带有DATETIME字段的表,它由一个BTree索引。现在我想用下面的语句查询它: SELECT count(us.CITY) as metric, us.CITY as Name, us.LATITUDE as latitude, us.LONGITUDE as longitude FROM FACT LEFT JOIN USER us ON us.ID_USER = FACT.USER WHERE ASSESSMENT_DATE BETWEEN FRO

我有一个带有DATETIME字段的表,它由一个BTree索引。现在我想用下面的语句查询它:

SELECT
  count(us.CITY) as metric,
  us.CITY as Name,
  us.LATITUDE as latitude,
  us.LONGITUDE as longitude
FROM
  FACT
LEFT JOIN
  USER us
ON
  us.ID_USER = FACT.USER
WHERE
  ASSESSMENT_DATE BETWEEN FROM_UNIXTIME(1601568552) AND FROM_UNIXTIME(1604028277)
GROUP BY us.CITY, us.LATITUDE, us.LONGITUDE;
说明:

+------+-------------+-------+--------+----------------------------+---------+---------+------------------------------+--------+----------------------------------------------+
| id   | select_type | table | type   | possible_keys              | key     | key_len | ref                          | rows   | Extra                                        |
+------+-------------+-------+--------+----------------------------+---------+---------+------------------------------+--------+----------------------------------------------+
|    1 | SIMPLE      | FACT  | ALL    | INDEX_FACT_ASSESSMENT_DATE | NULL    | NULL    | NULL                         | 762621 | Using where; Using temporary; Using filesort |
|    1 | SIMPLE      | us    | eq_ref | PRIMARY                    | PRIMARY | 46      | dwh0.FACT.USER,dwh0.FACT.ENV |      1 |                                              |
+------+-------------+-------+--------+----------------------------+---------+---------+------------------------------+--------+----------------------------------------------+
2 rows in set (0.001 sec)
+------+-------------+-------+--------+----------------------------+----------------------------+---------+------------------------------+--------+--------------------------------------------------------+
| id   | select_type | table | type   | possible_keys              | key                        | key_len | ref                          | rows   | Extra
     |
+------+-------------+-------+--------+----------------------------+----------------------------+---------+------------------------------+--------+--------------------------------------------------------+
|    1 | SIMPLE      | FACT  | range  | INDEX_FACT_ASSESSMENT_DATE | INDEX_FACT_ASSESSMENT_DATE | 5       | NULL                         | 132008 | Using index condition; Using temporary; Using filesort |
|    1 | SIMPLE      | us    | eq_ref | PRIMARY                    | PRIMARY                    | 46      | dwh0.FACT.USER,dwh0.FACT.ENV |      1 |
     |
+------+-------------+-------+--------+----------------------------+----------------------------+---------+------------------------------+--------+--------------------------------------------------------+
2 rows in set (0.001 sec)
有趣的是,只需手动将日期更改为DATETIME格式字符串,它就会使用索引。但是我认为FROM_UNIXTIME()函数应该返回完全相同的结果

SELECT
  count(us.CITY) as metric,
  us.CITY as Name,
  us.LATITUDE as latitude,
  us.LONGITUDE as longitude
FROM
FACT
LEFT JOIN
   USER us
ON
  us.ENV = FACT.ENV AND us.ID_USER = FACT.USER
WHERE
-- ASSESSMENT_DATE BETWEEN FROM_UNIXTIME(1596649101) AND FROM_UNIXTIME(1599108827)
  ASSESSMENT_DATE BETWEEN '2020-08-05 11:30:11.987' AND '2020-09-03 11:30:11.987'
GROUP BY us.CITY, us.LATITUDE, us.LONGITUDE;
说明:

+------+-------------+-------+--------+----------------------------+---------+---------+------------------------------+--------+----------------------------------------------+
| id   | select_type | table | type   | possible_keys              | key     | key_len | ref                          | rows   | Extra                                        |
+------+-------------+-------+--------+----------------------------+---------+---------+------------------------------+--------+----------------------------------------------+
|    1 | SIMPLE      | FACT  | ALL    | INDEX_FACT_ASSESSMENT_DATE | NULL    | NULL    | NULL                         | 762621 | Using where; Using temporary; Using filesort |
|    1 | SIMPLE      | us    | eq_ref | PRIMARY                    | PRIMARY | 46      | dwh0.FACT.USER,dwh0.FACT.ENV |      1 |                                              |
+------+-------------+-------+--------+----------------------------+---------+---------+------------------------------+--------+----------------------------------------------+
2 rows in set (0.001 sec)
+------+-------------+-------+--------+----------------------------+----------------------------+---------+------------------------------+--------+--------------------------------------------------------+
| id   | select_type | table | type   | possible_keys              | key                        | key_len | ref                          | rows   | Extra
     |
+------+-------------+-------+--------+----------------------------+----------------------------+---------+------------------------------+--------+--------------------------------------------------------+
|    1 | SIMPLE      | FACT  | range  | INDEX_FACT_ASSESSMENT_DATE | INDEX_FACT_ASSESSMENT_DATE | 5       | NULL                         | 132008 | Using index condition; Using temporary; Using filesort |
|    1 | SIMPLE      | us    | eq_ref | PRIMARY                    | PRIMARY                    | 46      | dwh0.FACT.USER,dwh0.FACT.ENV |      1 |
     |
+------+-------------+-------+--------+----------------------------+----------------------------+---------+------------------------------+--------+--------------------------------------------------------+
2 rows in set (0.001 sec)
有人能提到这样的问题吗?where子句是由grafana生成的,所以我不能更改它,但是如果它更改了某些内容,其余的我可以更改


谢谢你的建议

抱歉打扰了。。在大约10^5次插入后,它对这两种情况都有效。。。也许只是运气不好

您实际在生产中运行还是计划运行哪个版本?我很惊讶第一个查询没有使用索引,但是如果第二个版本可以工作,那么问题出在哪里呢?MySQL可能认为执行完整表扫描比将FROM_UNIXTIME转换应用于整个索引树更有效。您可以尝试使用提示强制使用索引,以查看是否有改进:
来自事实使用索引(index\u FACT\u ASSESSMENT\u DATE)
版本为10.3.29问题是,日期选择是由另一个应用程序宏(grafana)进行的,该宏使用UNIXTIME进行所有操作。所以我不能改变…@ThomasG谢谢你的提示,试过了,MariaDB仍然意味着不使用索引更有效--