gpt4 book ai didi

mysql - 为什么我的 ORDER BY BIGINT(20) 需要这么长时间?

转载 作者:太空宇宙 更新时间:2023-11-03 12:13:26 24 4
gpt4 key购买 nike

我正在尝试改进我的查询,以免花费这么长时间。有什么我可以尝试的吗?

我正在使用 InnoDB。

我的 table :

mysql> describe hunted_place_review_external_urls;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| worker_id | varchar(255) | YES | MUL | NULL | |
| queued_at | bigint(20) | YES | MUL | NULL | |
| external_url | varchar(255) | NO | | NULL | |
| place_id | varchar(63) | NO | MUL | NULL | |
| source_id | varchar(63) | NO | | NULL | |
| successful | tinyint(1) | NO | | 0 | |
+--------------+--------------+------+-----+---------+----------------+

我的查询:

mysql> select * from hunted_place_review_external_urls where worker_id is null order by queued_at asc limit 1;

1 row in set (4.00 sec)

mysql> select count(*) from hunted_place_review_external_urls where worker_id is null;
+----------+
| count(*) |
+----------+
| 19121 |
+----------+
1 row in set (0.00 sec)

即使我在 queued_atworker_id 上有一个索引,为什么它还是需要 4 秒?

这是此查询的EXPLAIN:

mysql> explain select * from hunted_place_review_external_urls where worker_id is null order by queued_at asc limit 1;
+----+-------------+-----------------------------------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------------------------+-------+---------------+-----------+---------+------+------+-------------+
| 1 | SIMPLE | hunted_place_review_external_urls | index | worker_id | queued_at | 9 | NULL | 67 | Using where |
+----+-------------+-----------------------------------+-------+---------------+-----------+---------+------+------+-------------+
1 row in set (0.00 sec)

当我删除 order by queued_at 部分时,它变得更快:

mysql> select * from hunted_place_review_external_urls where worker_id is null limit 1;

1 row in set (0.00 sec)

count(*) 较小时,它也会变得更快:

mysql> select count(*) from hunted_place_review_external_urls where worker_id is null;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)

mysql> select * from hunted_place_review_external_urls where worker_id is null order by queued_at asc limit 1;

1 row in set (0.00 sec)

我的 queued_at 值是以毫秒数表示的时间戳,例如 1398210069531

最佳答案

MySQL 使用 queued_at 索引来避免“使用文件排序”操作。看起来 MySQL 正在查看表中的每一行,这需要四秒钟。

MySQL是先利用索引获取queued_at值最小的行,然后访问底层数据页检查worker_id是否为NULL。 MySQL 通过索引,从 queued_at 的最低值到最高值。

对于找到的每个匹配行,MySQL 将该行添加到结果集中。

请注意,在找到所有 匹配行并准备好结果集之前,不会应用 LIMIT 子句。 (当找到第一个匹配行时没有“早出”,MySQL 仍然通过每一行查找最后一行。但至少,MySQL 避免了可能是昂贵的 Using filesort 操作以获取排序的行。)

您的其他查询表现出更好的性能,因为它们具有不同的访问计划,这可能使用索引来限制需要检查的行数。


要提高此特定查询的性能,您可以尝试添加索引:

... ON hunted_place_review_external_urls (worker_id, queued_at);

如果那不是一个选项,您可以尝试影响优化器使用不同的索引,并带有索引提示:

  select * 
from hunted_place_review_external_urls USING INDEX `worker_id`
where worker_id is null
order by queued_at asc
limit 1;

请注意,USING INDEX 提示引用索引的名称,而不是列的名称。从 EXPLAIN 输出来看,似乎有一个名为“worker_id”的索引。我猜测这个索引位于名为“worker_id”的列上,但这只是一个猜测。


顺便说一句,这与 queued_at 列被定义为 BIGINTINTSMALLINTVARCHAR

关于mysql - 为什么我的 ORDER BY BIGINT(20) 需要这么长时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23256916/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com