正在考虑 Mysql 索引,但仍有大表扫描

标签 mysql indexing

我有一个带有主键和几个日期相关字段的 Job 表 ...

 +------------------+---------------+------+-----+-------------------+----------------+
| Field            | Type          | Null | Key | Default           | Extra          |
+------------------+---------------+------+-----+-------------------+----------------+
| jobId            | bigint(20)    | NO   | PRI | NULL              | auto_increment |
| creationDateTime | datetime      | NO   | MUL | NULL              |                |
| lastModified     | timestamp     | NO   | MUL | CURRENT_TIMESTAMP |                |
+------------------+---------------+------+-----+-------------------+----------------+

此表有 426,579 行和以下索引

+---------+------------+--------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table   | Non_unique | Key_name                 | Seq_in_index | Column_name      | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+--------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+
| Job     |          0 | PRIMARY                  |            1 | jobId            | A         |      439957 |     NULL | NULL   |      | BTREE      |         |
| Job     |          1 | Job_lastModified_idx     |            1 | lastModified     | A         |      439957 |     NULL | NULL   |      | BTREE      |         |
| Job     |          1 | Job_creationDateTime_idx |            1 | creationDateTime | A         |      439957 |     NULL | NULL   |      | BTREE      |         |
+---------+------------+--------------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+

现在查询如...

select * from Job
 where jobId > 1000
 and creationDateTime between '2011-09-07 18:29:24' and '2011-09-07 20:00:33';

按预期运行得非常快(0s)

解释...

+----+-------------+-------+-------+----------------------------------+--------------------------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys                    | key                      | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+----------------------------------+--------------------------+---------+------+------+-------------+
|  1 | SIMPLE      | Job   | range | PRIMARY,Job_creationDateTime_idx | Job_creationDateTime_idx | 8       | NULL |   39 | Using where |
+----+-------------+-------+-------+----------------------------------+--------------------------+---------+------+------+-------------+

我看到针对 lastModified 而不是 creationDateTime 的等效查询的速度相同


但是稍微复杂一点的查询...

select * from Job
 where jobId > 1000
 and (lastModified between '2011-09-07 18:29:24' and '2011-09-07 20:00:33' 
      or creationDateTime between '2011-09-07 18:29:24' and '2011-09-07 20:00:33');

运行缓慢(9 秒)并且出于某种原因最终不得不进行更大的扫描,即使 正如预期的那样,它返回相同的行数 (40)

+----+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys                                         | key     | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+--------+-------------+
|  1 | SIMPLE      | Job   | range | PRIMARY,Job_lastModified_idx,Job_creationDateTime_idx | PRIMARY | 8       | NULL | 204581 | Using where |
+----+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+--------+-------------+

(注意:这个表有426579行,所以不确定204581是从哪里来的)


我原以为这会同样快?

为什么MySQL在这样组合时无法使用这些索引?

为 lastModified 和 creationDateTime 创建一些额外的复合索引根本没有帮助。

 create index test_idx1 on Job (lastModified,creationDateTime);
 create index test_idx2 on Job (jobId,lastModified,creationDateTime);

我一定是漏掉了一些简单的东西?

最佳答案

从@bill 的引用来看,我们的 mysql 版本 (5.0.67) 似乎不支持索引合并,因此在这种情况下没有索引会有所帮助。

我会选择一个快速的工会,谢谢大家!

关于正在考虑 Mysql 索引,但仍有大表扫描,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7366998/

相关文章:

php - 通过 url 中的特定 id 从 MySQL 数据库中获取数据

mysql - 要使用默认的 BatchConfigurer,上下文必须包含不超过一个数据源,找到 2

php - Cakephp 3 : Set virtual property with condition on belongsToMany association

vb.net - 如何更新 Lucene.NET 索引?

pandas - 将索引的 pandas 矩阵转换为平面数据框

mysql - 查询的意外行为

mysql - 索引这个 mysql 查询

php - 无法打开流 : HTTP request failed! HTTP/1.0 400 错误请求

android - 将数据从 mysql 数据库传输到 sqlite 数据库。(Android-JSON)

go - slice 索引奇怪的边缘情况