gpt4 book ai didi

sql - 能够加入 MySQL 的合理行数和表数是多少?

转载 作者:行者123 更新时间:2023-11-29 04:30:56 25 4
gpt4 key购买 nike

我有一个将位置映射到邮政编码的表格。例如,纽约州有大约 2000 个邮政编码。我有另一个表将邮件映射到它被发送到的邮政编码,但这个表有大约 500 万行。我想找到所有发送到纽约州的邮件,这看起来很简单,但查询速度慢得令人难以置信。我什至没能等到它完成。问题是有 500 万行吗?我忍不住想,如今 500 万对于计算机来说应该不是一个很大的数字……哦,所有内容都已编入索引。 SQL 不是为处理如此大的连接而设计的吗?

更新:正如人们所问,我已经用我正在使用的表定义和查询更新了这个问题。

-- Roughly 70,000 rows
CREATE TABLE `mail_zip` (
`mail_id` int(11) default NULL,
`zip` int(11) default NULL,
KEY `index_mail_zip_on_mail_id` (`mail_id`),
KEY `index_mail_zip_on_zip` (`zip`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

-- Roughly 5,000,000 rows
CREATE TABLE `geographies` (
`city_id` int(11) default NULL,
`postal_code` int(11) default NULL,
KEY `index_geographies_on_city_id` (`city_id`),
KEY `index_geographies_on_postal_code` (`postal_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

-- Query
select mz.mail_id from mail_zip mz join geographies g on mz.zip = g.postal_code where g.city_id = 36 limit 10;

更新 2:好吧,我撒谎了。使用适当的索引,上述查询工作正常。问题实际上是 order by 子句。请看下面两个几乎相同的查询:唯一的区别是“order by m.sent_on desc”,它给查询增加了额外的 4 分 30 秒!此外,使用解释,添加顺序使用文件排序,这一定是减慢速度的原因。但是,sent_on 是有索引的,为什么不使用索引呢?我一定没有正确制作索引。

-- Roughly 350,000 rows
CREATE TABLE `mail` (
`id` int(11) NOT NULL auto_increment,
`sent_on` datetime default NULL,
`title` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `index_mail_on_sent_on` (`sent_on`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1

-- Runs in 0.19 seconds
-- Query
select distinct(m.id), m.title from mail m join mail_zip mz on mz.mail_id = m.id join geographies g on g.postal_code = mz.zip where g.city_id = 36 limit 10;

+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+-----------------------+
| 1 | SIMPLE | mz | ALL | index_mail_zip_on_com_id,index_mail_zip_on_zip | NULL | NULL | NULL | 5260053 | Using temporary |
| 1 | SIMPLE | m | eq_ref | PRIMARY | PRIMARY | 4 | mz.com_id | 1 | |
| 1 | SIMPLE | g | ref | index_geographies_on_city_id,zip | zip | 5 | mz.zip | 1 | Using where; Distinct |
+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+-----------------------+

-- Runs in 4 minutes and 30 seconds
-- Query
select distinct(m.id), m.title from mail m join mail_zip mz on mz.mail_id = m.id join geographies g on g.postal_code = mz.zip where g.city_id = 36 order by m.sent_on desc limit 10;

+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+---------------------------------+
| 1 | SIMPLE | mz | ALL | index_mail_zip_on_com_id,index_mail_zip_on_zip | NULL | NULL | NULL | 5260053 | Using temporary; Using filesort |
| 1 | SIMPLE | m | eq_ref | PRIMARY | PRIMARY | 4 | mz.com_id | 1 | |
| 1 | SIMPLE | g | ref | index_geographies_on_city_id,zip | zip | 5 | mz.zip | 1 | Using where; Distinct |
+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+---------------------------------+

最佳答案

MySQL 完全有能力处理涉及 500 万行甚至更多行的连接。

您的问题可能是以下两件事之一:

  • 您缺少索引。
  • 您正在以优化器无法使用最佳索引的方式编写查询,例如,如果您使用的函数不是 sargable在您的连接条件中的索引列上。

既然您声称“所有内容都已编入索引”,我猜它是第二个。发布您的表信息和查询,我们应该能够帮助您解决问题。

您还可以对查询运行 EXPLAIN 以查看它正在使用哪些索引。

关于sql - 能够加入 MySQL 的合理行数和表数是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2569275/

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