Так что это может быть немного глупо, но альтернатива, которую я использовал, хуже. Я пытаюсь написать лист Excel, используя данные из моей базы данных и PHP инструмент под названием Box / Spout . Дело в том, что Box / Spout читает строки по одной за раз, и они не извлекаются через индекс (например, строки [10], строки [42], строки [156])
Мне нужно получить данные из база данных в порядке выхода строк. У меня есть база данных со списком клиентов, которая пришла через Import
, и я должен записать их в таблицу Excel. У них есть телефонные номера, электронные письма и адрес. Извините за путаницу ...: / Итак, я скомпилировал этот довольно сложный запрос:
SELECT
`Import`.`UniqueID`,
`Import`.`RowNum`,
`People`.`PeopleID`,
`People`.`First`,
`People`.`Last`,
GROUP_CONCAT(
DISTINCT CONCAT_WS(',', `PhonesTable`.`Phone`, `PhonesTable`.`Type`)
ORDER BY `PhonesTable`.`PhoneID` DESC
SEPARATOR ';'
) AS `Phones`,
GROUP_CONCAT(
DISTINCT CONCAT_WS(',', `EmailsTable`.`Email`)
ORDER BY `EmailsTable`.`EmailID` DESC
SEPARATOR ';'
) AS `Emails`,
`Properties`.`Address1`,
`Properties`.`city`,
`Properties`.`state`,
`Properties`.`PostalCode5`,
...(17 more `People` Columns)...,
FROM `T_Import` AS `Import`
LEFT JOIN `T_CustomerStorageJoin` AS `CustomerJoin`
ON `Import`.`UniqueID` = `CustomerJoin`.`ImportID`
LEFT JOIN `T_People` AS `People`
ON `CustomerJoin`.`PersID`=`People`.`PeopleID`
LEFT JOIN `T_JoinPeopleIDPhoneID` AS `PeIDPhID`
ON `People`.`PeopleID` = `PeIDPhID`.`PeopleID`
LEFT JOIN `T_Phone` AS `PhonesTable`
ON `PeIDPhID`.`PhoneID`=`PhonesTable`.`PhoneID`
LEFT JOIN `T_JoinPeopleIDEmailID` AS `PeIDEmID`
ON `People`.`PeopleID` = `PeIDEmID`.`PeopleID`
LEFT JOIN `T_Email` AS `EmailsTable`
ON `PeIDEmID`.`EmailID`=`EmailsTable`.`EmailID`
LEFT JOIN `T_JoinPeopleIDPropertyID` AS `PeIDPrID`
ON `People`.`PeopleID` = `PeIDPrID`.`PeopleID`
AND `PeIDPrID`.`PropertyCP`='CurrentImported'
LEFT JOIN `T_Property` AS `Properties`
ON `PeIDPrID`.`PropertyID`=`Properties`.`PropertyID`
WHERE `Import`.`CustomerCollectionID`=$ccID
AND `RowNum` >= $rnOffset
AND `RowNum` < $rnLimit
GROUP BY `RowNum`;
Итак, у меня есть индексы для каждого сегмента ON
и сегмента WHERE
. Когда значение RowNumber
примерно равно 0-> 2500, запрос выполняется отлично и выполняется в течение пары секунд. Но похоже, что время выполнения запроса экспоненциально умножается при увеличении RowNumber.
У меня есть EXPLAIN
здесь: и в pastebin (https://pastebin.com/PksYB4n2)
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE Import NULL ref CustomerCollectionID,RowNumIndex CustomerCollectionID 4 const 48108 8.74 Using index condition; Using where; Using filesort;
1 SIMPLE CustomerJoin NULL ref ImportID ImportID 4 MyDatabase.Import.UniqueID 1 100 NULL
1 SIMPLE People NULL eq_ref PRIMARY,PeopleID PRIMARY 4 MyDatabase.CustomerJoin.PersID 1 100 NULL
1 SIMPLE PeIDPhID NULL ref PeopleID PeopleID 5 MyDatabase.People.PeopleID 8 100 NULL
1 SIMPLE PhonesTable NULL eq_ref PRIMARY,PhoneID,PhoneID_2 PRIMARY 4 MyDatabase.PeIDPhID.PhoneID 1 100 NULL
1 SIMPLE PeIDEmID NULL ref PeopleID PeopleID 5 MyDatabase.People.PeopleID 5 100 NULL
1 SIMPLE EmailsTable NULL eq_ref PRIMARY,EmailID,DupeDeleteSelect PRIMARY 4 MyDatabase.PeIDEmID.EmailID 1 100 NULL
1 SIMPLE PeIDPrID NULL ref PeopleMSCP,PeopleID,PropertyCP PeopleMSCP 5 MyDatabase.People.PeopleID 4 100 Using where
1 SIMPLE Properties NULL eq_ref PRIMARY,PropertyID PRIMARY 4 MyDatabase.PeIDPrID.PropertyID 1 100 NULL
Прошу прощения, если форматирование абсолютно ужасное. Я не уверен, как выглядит хорошее форматирование, поэтому я, возможно, немного перепутал его с ошибками, плюс запутались вкладки.
То, что я хочу знать, - это как ускорить время запроса. Базы данных очень большие, как в десятках миллионов строк. И они не всегда такие, потому что наши таблицы постоянно меняются, однако я хотел бы иметь возможность справиться с этим, когда они есть.
Я пытался использовать LIMIT 2000, 1000, например, но я знаю, что это менее эффективен, чем использование индексированного столбца. Поэтому я переключился на RowNumber. Я чувствую, что это было хорошее решение, но кажется, что MySQL все еще циклически повторяет каждую строку перед переменной смещением, что побеждает цель моего индекса ... Я думаю? Я не уверен. Я также в основном разделил этот конкретный запрос примерно на 10 отдельных запросов и запускал их один за другим для каждой строки файла Excel. Это занимает много времени ... слишком долго. Это быстро, но, очевидно, у меня проблема.
Любая помощь будет принята с благодарностью, и спасибо заранее. Еще раз прошу прощения за отсутствие организации почты.