Предположим, что мне нужно запросить партнеров корпорации. У меня есть таблица «транзакции», которая содержит данные о каждой сделанной транзакции.Оптимизация запроса MySQL с большим предложением IN() или присоединением к производной таблице
CREATE TABLE `transactions` (
`transactionID` int(11) unsigned NOT NULL,
`orderID` int(11) unsigned NOT NULL,
`customerID` int(11) unsigned NOT NULL,
`employeeID` int(11) unsigned NOT NULL,
`corporationID` int(11) unsigned NOT NULL,
PRIMARY KEY (`transactionID`),
KEY `orderID` (`orderID`),
KEY `customerID` (`customerID`),
KEY `employeeID` (`employeeID`),
KEY `corporationID` (`corporationID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Это довольно просто, чтобы запросить эту таблицу для окружающих, но есть поворот: Рекордная сделка регистрируются один раз на одного работника, и поэтому может быть несколько записей для одной корпорации в порядок.
Например, если сотрудники A и B от корпорации 1 участвовали в продаже пылесоса корпорации 2, в таблице «транзакции» было бы две записи; один для каждого сотрудника, и как для корпорации 1. Однако это не должно влиять на результаты. Торговля от корпорации 1, независимо от того, сколько ее сотрудников была вовлечена, должна рассматриваться как одна.
Легко, думал я. Я просто сделать присоединиться на производной таблице, например, так:
SELECT corporationID FROM transactions JOIN (SELECT DISTINCT orderID FROM transactions WHERE corporationID = 1) AS foo USING (orderID)
Запрос возвращает список корпораций, которые принимали участие в торгах с корпорацией 1. Это именно то, что мне нужно, но это очень медленно, потому что MySQL не может использовать индекс corporationID для определения производной таблицы. Я понимаю, что это относится ко всем подзапросам/производным таблицам в MySQL.
Я также пытался запросить коллекцию orderID отдельно и использовать смехотворно большое предложение IN() (typhically 100 000+ ID), но, как оказалось, у MySQL есть проблемы с использованием индексов на смехотворно больших предложениях IN() а также, в результате время запроса не улучшается.
Есть ли другие варианты, или я их исчерпал?
Спасибо за ваше время, Фил. Первый запрос не может использовать индекс по той же причине, что и моя производная таблица. Второй использует правильные индексы, но не возвращает правильные данные. Я немного скорректировал его, и, хотя он использует индекс, он помечен как «использование временных» и «using filesort», и, по-видимому, по этой причине он занимает столько же времени, сколько запросы, которые не могут использовать индекс. Я думаю, что ты на что-то. –
Жаль, что это не сработало. Это было именно то, что я хотел бы попробовать. Я нахожу, что для некоторых запросов MySQL просто не может сделать это быстро, поэтому вам нужно найти обходной путь. Проводка некоторых данных позволит другим играть с ней. –