【问题标题】:How to optimize the query of datetime condition?如何优化日期时间条件的查询?
【发布时间】:2019-06-04 08:52:45
【问题描述】:

我有一个表 cashflow 和 4 个索引 [is_dp]、[is_wd]、[is_dis]、[time]。

`is_dp`   tinyint(1) => (0,1)
`is_wd`   tinyint(1) => (0,1)
`is_dis`  tinyint(1) => (0,1)
`time`    datetime

这个表有 300 万行。

我的查询是:

1. SELECT * FROM `cashflow` WHERE is_dp = 1 AND time >= '2019-05-01 00:00:00' AND time <= '2019-05-31 23:59:59';

2. SELECT * FROM `cashflow` WHERE is_wd = 1 AND time >= '2019-05-01 00:00:00' AND time <= '2019-05-31 23:59:59';

3. SELECT * FROM `cashflow` WHERE is_dis = 1 AND time >= '2019-05-01 00:00:00' AND time <= '2019-05-31 23:59:59';

索引time 不适用于每个键 [is_dp]、[is_wd]、[is_dis]。

解释:

| query | possible_keys  |  key   | key_len |  ref  | rows    | Extra                               |
| 1.    | is_dp,time     | time   | 8       | NULL  | 242616  | Using index condition; Using where; |
| 2.    | is_wd,time     | is_wd  | 1       | const | 494546  | Using where;                        |
| 3.    | is_dis,time    | is_dis | 1       | const | 1089870 | Using where;                        |

如何优化?

还是复合键是个好办法?

ADD KEY `dp_time` (`is_dp`,`time`);
ADD KEY `wd_time` (`is_wd`,`time`);
ADD KEY `dis_time` (`is_dis`,`time`);

非常感谢!

【问题讨论】:

  • 是的,复合索引可能会有所帮助。
  • @Barmar 知道了。谢谢。

标签: mysql optimization indexing


【解决方案1】:

对于 那些 3 SELECTs,您需要所有 3 个那些复合 索引。建议的 4 列索引对它们中的任何一个都不是最佳的。

索引从左边开始使用。使用INDEX(is_dp, is_wd, is_dis, time),查询1 可以使用is_dp,但是当它到达is_wd 时会退出索引。其他两个查询根本无法使用索引。

(我刚才说的并不完全正确,但它们的效率并不,即使使用了。)

我的Cookbook 解释了如何构建最佳索引。

Using index condition -- 暗示 InnoDB 将在 Engine 内部进行大部分或全部过滤,而不是 Handler。 (好吧,这是一个神秘的解释;该查询不是讨论 ICP(索引条件下推)的好工具。)

Using where - 使用了一些WHERE。比较模糊。

key_len = 1 - 表示只使用了索引的 1 个字节;大概是is_wd

【讨论】:

  • @James 如果我使用复合索引,我知道它将使用大量存储来创建这些复合索引。因为time 字段类型是日期时间。比所有这 3 个综合指数都要好吗?
  • @BinglinLai - 不,把范围 (time) 放在最后,就像我把 aaa 放在最后一样。
  • @James 知道了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 2019-05-29
  • 2018-08-11
相关资源
最近更新 更多