У меня есть одна таблица, которая отображает местоположения в почтовые индексы. Например, штат Нью-Йорк имеет около 2000 почтовых индексов. У меня есть другая таблица, которая сопоставляет почту с почтовыми кодами, на которые она была отправлена, но в этой таблице около 5 миллионов строк. Я хочу найти всю почту, которая была отправлена в штат Нью-Йорк, которая кажется достаточно простой, но запрос невероятно медленный. Я не мог даже ждать достаточно долго, чтобы это закончилось. Проблема в том, что там 5 миллионов строк? Я не могу не думать, что 5 миллионов не должно быть таким большим числом для компьютера в эти дни ... О, и все проиндексировано. Разве 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 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 |
+----+-------------+-------+--------+--------------------------------------------------------+---------+---------+----------------------+---------+---------------------------------+