让我们采取以下方案。
我们有
SELECT id
FROM table
WHERE name='name'
ORDER
BY id DESC
LIMIT 100
以及与LIMIT 5
完全相同的查询。
LIMIT 100
查询大约需要0.2s,而LIMIT 5
查询大约需要0.008s。 (甚至更高的LIMIT的1000执行时间上升到2秒!)
现在我们使用时间戳代替id。
我们有
SELECT id
FROM table
WHERE name='name'
ORDER
BY timestamp DESC
LIMIT 100
,并再次使用LIMIT 5
进行完全相同的查询。
LIMIT 100
查询大约需要0.4s,而LIMIT 5
查询也需要0.4s。 (将LIMIT设置为1000不会太大影响执行时间。
该表如下构建。 id
是主键,并且auto_increment是活动的。该表有500.000行。有100个不变的名称。每隔10分钟,我们会将所有名称及其最近的更新(带有时间戳)插入到表中。这意味着我们的表如下所示:
+-----+-------+---------------------+--+--+
| id | name | timestamp | | |
+-----+-------+---------------------+--+--+
| 1 | mark | 2019-03-31 09:00:02 | | |
+-----+-------+---------------------+--+--+
| 2 | peter | 2019-03-31 09:00:02 | | |
+-----+-------+---------------------+--+--+
| 3 | john | 2019-03-31 09:00:02 | | |
+-----+-------+---------------------+--+--+
| ... | ... | ... | | |
+-----+-------+---------------------+--+--+
| 101 | mark | 2019-03-31 09:10:02 | | |
+-----+-------+---------------------+--+--+
| 102 | peter | 2019-03-31 09:10:02 | | |
+-----+-------+---------------------+--+--+
| 103 | john | 2019-03-31 09:10:02 | | |
+-----+-------+---------------------+--+--+
因此,在使用name ='mark'的查询之后,它应如下所示:
+-----+------+---------------------+--+--+
| id | name | timestamp | | |
+-----+------+---------------------+--+--+
| 501 | mark | 2019-03-31 09:50:02 | | |
+-----+------+---------------------+--+--+
| 401 | mark | 2019-03-31 09:40:02 | | |
+-----+------+---------------------+--+--+
| 301 | mark | 2019-03-31 09:30:02 | | |
+-----+------+---------------------+--+--+
| 201 | mark | 2019-03-31 09:20:02 | | |
+-----+------+---------------------+--+--+
| 101 | mark | 2019-03-31 09:10:02 | | |
+-----+------+---------------------+--+--+
| 1 | mark | 2019-03-31 09:00:02 | | |
+-----+------+---------------------+--+--+
| ... | ... | ... | | |
+-----+------+---------------------+--+--+
我现在的问题是,与完全相同但由id DESC
进行排序的查询相比,为什么LIMIT
进行的排序在timestamp DESC
较高的情况下执行这么慢(限制1000在2s以上) (极限1000约为0.4s)。
我试图更改表并将索引添加到id,但这并没有改变。 问题是否出在id之间的空隙上? (501,401,301 ...)。
经过三天的谷歌搜索和尝试不同的查询后,什么都没有改变,关于这个奇怪行为的我的问题尚未得到答案。
说明ID为ID的查询
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | name | index | NULL | PRIMARY | 4 | NULL | 1000 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
还有带时间戳的说明查询:
+----+-------------+-------+------+---------------+------+---------+------+--------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-----------------------------+
| 1 | SIMPLE | name | ALL | NULL | NULL | NULL | NULL | 500000 | Using where; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+--------+-----------------------------+
@ niklaz,id类型为int(10)
@scaisEdge
表架构:
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
+-----------+------------------+------+-----+---------+----------------+
| name | varchar(10) | NO | | NULL | |
+-----------+------------------+------+-----+---------+----------------+
| timestamp | timestamp | NO | | NULL | |
+-----------+------------------+------+-----+---------+----------------+
答案 0 :(得分:2)
间隙与列ID的内容无关。您应该尝试在表上添加复合冗余索引
create index idx1 on my_table(name, id)
可能是与缓存值有关的差距..尝试在单独的会话中执行查询。